【问题标题】:Haskell turning list of tuples into list of listsHaskell将元组列表转换为列表列表
【发布时间】:2019-04-06 21:26:42
【问题描述】:

我正在尝试将元组列表转换为列表列表。例如,如果我有列表[(9,1), (6,3), (4,1)],那么这将变成[[9, 6, 4],[6],[6]]。发生的情况是,在元组列表中[(a,b)]a 代表 0-9 之间的数字,b 代表该数字的出现,a 将始终是唯一的。

我要做的事情是遍历列表n 次,其中n = maximum b in the list of tuples. 每次遍历列表时,我都会将a 放入列表中,然后将b 递减1.如果b == 0,那我就跳过它。

因此,在我的示例中,我将[9,6,4] 放入一个列表中,然后递减每个b,所以现在列表看起来像[(9,0),(6,2),(4,0)]。然后再看一遍,我取[6],元组列表现在看起来像[(9,0), (6,1), (4,0)]。最后,最后一次取[6],现在元组列表中的b0,这样就完成了。

我创建了一个函数,它从元组列表中获取第一个元素,如果 b >= 1,但我不知道如何在更新后的列表中迭代它,所有 `b - 1'每个元组。

turnIntList :: [(Integer, Integer)] -> [[Integer]]
turnIntList [] = []
turnIntList x = ([map (\(a, b) -> case (a,b) of  _ | b >= 1 -> a | otherwise -> -1) x])

我还尝试创建另一个辅助函数,该函数接受一个元组列表并将它们转换为一个列表,具体取决于b 的大小。在主函数中,我会尝试发送 [(a, 1), (b, 1)...] 来创建列表,然后在此处跟踪递减 b 直到完成。所以,对于这个函数:

pairingL :: [(Integer, Integer)] -> [Integer] -> [Integer]
pairingL ((a,b):xs) l -- = if b /= 0 then [a,b-1] else []
    | null xs = if b == 1 then [a] ++ l else if b > 1 then [a] ++ l ++ pairingL [(a,b-1)] l else l
    | otherwise = 
        if b /= 0 then [a] ++ l ++ pairingL ((a,b-1):xs) l else pairingL xs l


pairingL [(9,1), (7,2), (5,1)]
[9,7,7,5]

pairingL [(1,1), (2,1), (3,1)]
[1,2,3]

pairingL [(1,2), (2,2), (3,2)]
[1,1,2,2,3,3]

我尝试过解压缩列表并使用它、迭代和重复,但我不知道如何让函数多次遍历列表并使用新的 b 更新列表值然后再去。

总之,我想做的是:

    turnIntList [(9,3),(5,1),(2,1)]
    [[9,5,2],[9],[9]]

    turnIntList [(1,1),(2,1),(3,1),(4,1)]
    [[1,2,3,4]]

    turnIntList [(1,2),(2,2),(3,2)]
    [[1,2,3],[1,2,3]]

    turnIntList [(4,2),(6,1)]
    [[4,6],[4]]

流程: 我从元组中取出第一个元素,将它们添加到列表中,然后将第二个元素减去 1。对列表中的每个元组执行此操作后,我重复该过程,直到每个元组的所有第二个元素都为 0

重要提示:同样,在元组列表 [(a,b)] 中,a 将始终是 0-9 的唯一数字,b >= 0

【问题讨论】:

  • 你还有其他的例子吗?
  • @Elmex80s 对不起,我应该放超过 1 个例子。我又添加了一些,更清楚地解释了这个过程
  • 谢谢。输入输出就足够了。循环的第一步可能会分散注意力
  • 为了您的娱乐,turnIntList = transpose . map (uncurry (flip replicate)) 也可以使用,尽管在技术上使用Int 而不是Integer 签名[(a, Int)] -> [[a]]
  • 或者更短,turnIntList = (>>= uncurry (flip replicate))

标签: haskell functional-programming lazy-evaluation


【解决方案1】:

这可能

turnIntList :: [(Integer, Integer)] -> [[Integer]]
turnIntList [] = [] -- if it doesn’t compile use [[]]
turnIntList ls = [i | (i, _) <- ls] : turnIntList [(i, n - 1) | (i, n) <- ls, n - 1 > 0]

【讨论】:

  • 我知道必须有一个更简单的列表解析解决方案。我对 Haskell 很陌生,这是我仍然很薄弱的领域之一。肯定会更多地阅读它。我不明白的一件事是,我想这会引发 n not in scope 错误,因为它没有在任何地方明确声明,但是这很有效。
  • n 受内部列表理解@WilliamJones 的模式匹配约束
猜你喜欢
  • 1970-01-01
  • 2011-03-05
  • 2023-03-11
  • 2018-12-19
  • 2012-06-05
  • 1970-01-01
  • 2022-09-27
  • 2020-02-28
  • 1970-01-01
相关资源
最近更新 更多