如何在 Haskell 中总结元组列表?

Jon*_*han 1 haskell

这是一个超级简单的问题,但我似乎找不到答案。假设我在 Haskell 中有一个元组列表,

myList = [("foo", 2), ("bar", 4), ("foo", 6), ("bar", 1)]
Run Code Online (Sandbox Code Playgroud)

我想按第一个元素对它们进行分组,然后在第二个元素上将它们相加,我该怎么做?

这个例子将输出 [("foo", 8), ("bar", 5)]

Zet*_*eta 5

这在很大程度上取决于你的键(在你的元组的第一个元素)是否Ord还是只Eq。如果它只是 in Eq,那么partition基于 - 的方法就可以了:

import Data.List (partition)

sumByKey :: (Eq k, Num v) => [(k, v)] -> [(k, v)]
sumByKey []         = []
sumByKey ((k,v):xs) = (k,v + sum vs) : sumByKey bs
  where
    vs       = map snd ks
    (ks, bs) = partition ((k ==) . fst) xs
Run Code Online (Sandbox Code Playgroud)

但是,如果您Ord手头有并且对外部依赖项很好,那么Map可以使代码更容易:

import Data.Map.Strict

sumByKey :: (Ord k, Num v) => [(k, v)] -> [(k, v)]
sumByKey = toList . fromListWith (+)
Run Code Online (Sandbox Code Playgroud)