首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何从两个列表创建一个列表,从这些列表创建一个元素

如何从两个列表创建一个列表,从这些列表创建一个元素
EN

Stack Overflow用户
提问于 2017-01-22 15:14:41
回答 2查看 1.1K关注 0票数 2

我是哈斯克尔新来的。我试图使用递归编写一个函数,给定两个列表(它们需要相同的类型),交错它们的元素(在第一个列表和第二个列表之间交替使用元素)。当其中一个列表中没有更多的元素时,它就停止了,结果就是实现了那么远的列表。

代码语言:javascript
复制
interChange :: [a] -> [b] ->[(a,b)]
interChange _ [] = []
interChange [] _ = []
interChange (x:xs) (y:ys) =  (x,y) : interChange xs ys

我的输出示例:

代码语言:javascript
复制
interChange [1,2,3] [4,5,6]
 [(1,4),(2,5),(3,6)]

所需输出的示例如下:

代码语言:javascript
复制
interChange [1,2,3] [4,5,6]
[1,4,2,5,3,6]

谢谢你的帮忙

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-01-22 15:20:38

你的interChange和前奏曲的zip是一样的。

代码语言:javascript
复制
ghci> zip [1,2,3] ["wibble", "wobble", "wubble"]
[(1,"wibble"),(2,"wobble"),(3,"wubble")]

要编写指定的函数,实际上需要一对相同类型的列表。我们输出一个特定类型的列表,所以该列表中的所有元素也必须具有该类型。

代码语言:javascript
复制
interleave :: [a] -> [a] -> [a]

您可以以递归的方式实现这一点,方法是传递一个Bool,指示您应该从哪个列表中获取下一个元素:

代码语言:javascript
复制
interleave = go True
    where go _ [] ys = ys
          go _ xs [] = xs
          go True (x:xs) ys = x : go False xs ys
          go False xs (y:ys) = y : go True xs ys

go的最后两个子句之间计算ping-pongs,直到其中一个输入列表为空为止,因此我们只返回另一个输入列表的其余部分。(如果希望它的行为更像zip,可以通过返回[]而不是xsys来截断输出。)

但我总是建议在可能的情况下避免递归到更高级别的程序。我们可以将这个函数写成一个管道:

  1. 使用zip对输入列表的元素
  2. 将结果列表中的每个元组转换为两个元素列表:map (\(x, y) -> [x, y])
  3. 使用concat将结果列表平平。

代码看起来如下:

代码语言:javascript
复制
interleave xs ys = concat $ map (\(x, y) -> [x, y]) $ zip xs ys

我发现这段代码比递归代码更容易理解,递归代码要求您对控制流进行推理--这只是一系列高级指令。

顺便说一句,您可以通过将中间map拖到concatzip中来删除它。

代码语言:javascript
复制
interleave xs ys = concatMap (\(x, y) -> [x, y]) $ zip xs ys
interleave xs ys = concat $ zipWith (\(x, y) -> [x, y]) xs ys
票数 3
EN

Stack Overflow用户

发布于 2017-01-22 15:36:43

interChange被两个非空列表( (x:xs)(y:ys) )调用时,输出应该是以xy开始的列表,然后是更多的东西。所以你应该写点什么

代码语言:javascript
复制
interChange (x:xs) (y:ys) =  x : y : ...
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41792586

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档