首页 > 解决方案 > Haskell 将不同索引处的 2 个列表的元素组合在一起

问题描述

为这个糟糕的标题道歉,我不太确定如何用语言来描述它,但这就是我的意思。如果您知道更好的表达方式,请告诉我。

假设我有 2 个长度相同的列表。

[a, b, c] [x, y, z]

我想创建列表

[[a, y, z], [b, x, z], [c, x, y]]

基本上对于list1 的每个元素,我希望list2 中第一个元素的不同索引处的2 个元素。

因此,对于索引 0 处的“a”,其他 2 个是索引 1 处的“y”和索引 2 处的“z”。

我很确定我知道如何使用索引来做到这一点,但是,我知道这不是很有效,我想看看是否有更实用的解决方案。

谢谢你。

标签: listhaskellfunctional-programmingcombinations

解决方案


我会用拉链来做。这是我在许多项目中编写的函数,我已经记住了它:

zippers :: [a] -> [([a], a, [a])]
zippers = go [] where
    go b [] = []
    go b (h:e) = (b, h, e) : go (h:b) e

(这实际上返回的信息比我们在此应用程序技术上所需的信息要多。但它是通用形式——在许多情况下很有用,其中仅返回前缀/后缀对并省略当前焦点的受限版本有时还不够.)

有了这个工具,我们可以zip(不同类型的 zip!)将一个列表中的值与另一个列表的 zippers 放在一起。

combine :: [a] -> [a] -> [[a]]
combine xs ys = zipWith (\x (b, h, e) -> reverse b ++ [x] ++ e) xs (zippers ys)

在 ghci 中尝试一下:

> combine "abc" "xyz"
["ayz","xbz","xyc"]

推荐阅读