计算元素的出现次数

时间:2012-06-07 14:58:55

标签: scala list haskell dictionary list-comprehension

计算列表中的所有元素是Haskell中的一行代码:

count xs = toList (fromListWith (+) [(x, 1) | x <- xs])

以下是一个示例用法:

*Main> count "haskell scala"
[(' ',1),('a',3),('c',1),('e',1),('h',1),('k',1),('l',3),('s',2)]

这个功能在Scala中也可以如此优雅地表达吗?

4 个答案:

答案 0 :(得分:36)

scala> "haskell scala".groupBy(identity).mapValues(_.size).toSeq
res1: Seq[(Char, Int)] = ArrayBuffer((e,1), (s,2), (a,3), ( ,1), (l,3), (c,1), (h,1), (k,1))

答案 1 :(得分:6)

从Data.List库中调用group

group :: [a] -> [[a]]

给我们:

map (head &&& length) . group . sort

列表友好且相对“天真”的实现。

答案 2 :(得分:1)

另一种实施方式:

def count[A](xs: Seq[A]): Seq[(A, Int)] = xs.distinct.map(x => (x, xs.count(_ == x)))

答案 3 :(得分:0)

想要直译,让我们试试这个:

// Implementing this one in Scala
def fromSeqWith[A, B](s: Seq[(A, B)])(f: (B, B) => B) =
    s groupBy (_._1) mapValues (_ map (_._2) reduceLeft f)

def count[A](xs: Seq[A]) = fromSeqWith(xs map (_ -> 1))(_+_).toSeq

Scala的groupBy使其变得比它需要的更复杂 - 已经有groupWithgroupInto的要求,但它们没有使Odersky成为标准库包含的标准。