Подтвердить что ты не робот

Подсчет элементов элементов

Подсчет всех элементов в списке является однострочным в 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?

4b9b3361

Ответ 1

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))

Ответ 2

Вызвать group из библиотеки Data.List,

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

дает нам:

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

упрощающая список и относительно "наивная" реализация.

Ответ 3

Другая реализация:

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

Ответ 4

Переходя к буквальному переводу, попробуйте это:

// 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 делает это более сложным, чем это необходимо - были вызовы для groupWith или groupInto, но они не сделали стандарт Odersky для стандартного включения библиотеки.