【发布时间】:2012-08-20 13:25:53
【问题描述】:
我可以将什么运算符传递给允许我在元组列表中对按元组项 1 分组的元组项 2 进行求和的折叠变体之一?
所以,假设我有清单:
[ ('A', 1) , ('A', 3) , ('B', 4 ) , ('C', 10) , ('C', 1) ]
我想生成列表:
[ ('A', 4) , ('B', 4) , ('C', 11) ]
你可以看到它是一个 Haskell 化的表,所以这里的表的实际表示并不重要;这是获取输入数据并生成我感兴趣的输出的方法。我是 Haskell 新手,并且有 C/C++/C# 的背景。我已经完成了足够多的教程来识别此处折叠的应用,但无法弄清楚似乎需要的子折叠。
编辑: 如果这对其他人有帮助,这是我使用 group、foldl1 和 map 的解决方案,灵感来自 ingo 的回复:
import qualified Data.List as List
mygroup :: [ (Char,Int) ] -> [ [(Char,Int)] ]
mygroup = List.groupBy (\x y -> fst x == fst y)
myfold :: [(Char,Int)] -> (Char,Int)
myfold = foldl1 (\x y -> (fst x, snd x + snd y))
mysum :: [(Char,Int)] -> [(Char,Int)]
mysum = map myfold . mygroup
运行时:
*ListSum> mysum [ ('A',1) , ('A',2) , ('B',3) , ('C',4) , ('C',5) ]
[('A',3),('B',3),('C',9)]
mygroup 展示了如何通过提供等价运算符来创建组。如果两个成员的第一个元组项相同,则表示两个成员在同一个组中。
myfold 展示了如何对两个元组求和。它使用列表中的第一个元组作为折叠的初始状态,并根据每个元组的第二项之和组成一个结果元组。
mysum 使用 map 组合这两个函数。
我可能会花更多的时间来看看我是否可以打破对数据架构的依赖,目前是 [(Char,Int)]。我认为这意味着提供 groupBy 运算符和 fold 运算符,并且可能只是组合 groupBy、foldl1 和 map 的练习。我是新手。
我没有积分可以得到积分吗? :)
【问题讨论】:
-
你有没有尝试过?
-
@dbaupp:不。我看不出如何编写折叠运算符来执行子折叠。
-
@DanielWagner:谢谢,这个建议很好地支持了 shang 的回答。