【问题标题】:How can I build a list from another list, creating multiple elements for each element in the original list?如何从另一个列表构建一个列表,为原始列表中的每个元素创建多个元素?
【发布时间】:2011-11-10 04:40:47
【问题描述】:

我想做类似的事情

[(x, y, x+y) | (x,y) <- original]

当然,这会返回如下内容:

[(0, 0, 0), (0, 1, 1), (1, 1, 2)]

我想要的是这样的:

[0, 0, 0, 0, 1, 1, 1, 1, 2]

我对 Haskell 很陌生,不熟悉它的习语。我怎样才能在 Haskell 中做到这一点?

【问题讨论】:

  • 将来您可以使用hoogle,而不是像您(现已删除)答案中那样构建功能。
  • @ThomasM.DuBuisson:这真的很酷,谢谢!

标签: list haskell list-comprehension


【解决方案1】:

首先,对类型的谩骂。您正在从名为 original 的列表中绘制对 (x,y)。 original 必须是对的列表,original :: [(a,b)],例如[(1,6), (4,9)]。然后为每个元素构造一个元组,从而得到一个元组列表的结果。我猜测您从不想要任何元组,但实际上希望列表中的一些元素由您的函数组合并将结果连接到一个新列表中。

您可能正在寻找concatMap 函数:

> :t concatMap
concatMap :: (a -> [b]) -> [a] -> [b]
> concatMap (\x -> [x,x+1,x+7]) [1,2,3]
[1,2,8,2,3,9,3,4,10]

如果你真的想一次消耗两个(或更多)元素,那么就会缺少一些细节,例如如果你有奇数个元素并且天气或元素不重复该怎么办(所以你会看到@987654327 @ 作为两个输入 1,22,3)。

如果元素重复,那么这只是一个concatMap 和一个zip

> let ls = [1,2,3] in concatMap (\(x,y) -> [x,y,x+y]) (zip ls (drop 1 ls))
[1,2,3,2,3,5]

但如果您想将它们视为 [1,2] 和 [3],那么您最好编写自己的函数:

func [] = []
func [x] = [[x]] -- What do you want with the odd remaining element?
func (x:y:rest) = [x,y,x+y] : func rest

> concat (func [1,2,3])
[1,2,3,3]

【讨论】:

    【解决方案2】:

    看起来你只是在做一个不确定的选择——这正是列表推导的目的!

    [v | (x,y) <- original, v <- [x, y, x+y]]
    

    【讨论】:

      【解决方案3】:

      例如,您可以创建一个列表列表,然后使用concat 将其展平。

      concat [[x, y, x+y] | (x, y) <- original]
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-01-31
        • 1970-01-01
        • 2018-12-03
        • 1970-01-01
        • 1970-01-01
        • 2020-04-13
        • 1970-01-01
        相关资源
        最近更新 更多