【发布时间】:2014-06-13 14:52:29
【问题描述】:
我正在寻找类型的函数
[[(a, b)]] -> [(a, [b])]
和Hoogle tells me there isn't one,所以我写了这个:
transpose :: (Eq a) => [[(a, b)]] -> [(a, [b])]
transpose alists = uncurry zip $ foldl combine ([], []) alists
where combine memo new = foldl tally memo new
tally ([], []) (k, v) = ([k], [[v]])
tally ((ksHead:ksRest), (vsHead:vsRest)) (k, v) =
if k == ksHead
then (ksHead:ksRest, (v:vsHead):vsRest)
else (ksHead:ks, vsHead:vs)
where (ks, vs) = tally (ksRest, vsRest) (k, v)
按重要性排序:
- 实际上是否存在 Hoogle 不知道的内置函数?
-
transpose是这个东西的正确名称吗? - 是否有更好(更易读和/或性能更高)的编写方式?
编辑
因为有人对味道感兴趣:
我正在编写一个堆栈排名应用程序,来自用户的选票以[(Candidate, Rank)] 的形式出现。例如,为了通过Borda count 计算获胜者,我需要通过组合这些选票来计算每个Candidate 的排名。也欢迎对更普遍的问题发表评论。
【问题讨论】:
-
我不认识这个函数,但是
transpose已经是别的东西了。 -
你到底想要这个函数做什么?您的实现执行
transpose [[(1, 2), (2, 3)], [(4, 5), (6, 7)], [(4, 10)]] == [(1,[2]),(2,[3]),(4,[10,5]),(6,[7])],看起来它只是执行concat,然后执行groupBy,然后聚合第二个元素。你绝对可以比你写的简单得多,但我怀疑它已经存在了。