2015-03-05 4 views
1

Я часто пишу тот же код для разбиения на разделы последовательности кортежей:Partition последовательность кортежей в Скале

def groupBy[A, B](s: Seq[(A, B)]) : Map[A, Seq[B]] = s.groupBy (_._1) map { case (k, values) => (k, values.map(_._2))} 

Есть ли лучший способ?

+1

Ваша подпись 'groupBy' очень специфична, поэтому в стандартной библиотеке не существует метода, который выполняет именно это. Во всяком случае, это очень красноречиво? –

+1

Немного более кратким: 'groupBy (_._ 1) .mapValues ​​(_. Map (_._ 1))', но затем вы столкнулись с проблемой с 'mapValues' (http://blog.bruchez.name/2013/ 02/mapmap-против-mapmapvalues.html) –

ответ

1

Scalaz foldMap понятнее, хотя, возможно, менее эффективным:

import scalaz._, Scalaz._ 

def groupBy[A, B](l: List[(A,B)]) = l foldMap {t => Map(t._1 → List(t._2))} 

Поскольку Scalaz предлагает только экземпляры класса типов для конкретных типов, таких как List или Vector вы можете использовать только те, не Seq. Если вы хотите общую версию вы можете использовать класс типов явно:

def groupBy[S[_]: Foldable, A, B](s: S[(A, B)]) = 
    s foldMap {t => Map(t._1 → List(t._2))} 

Это будет работать для List, Vector, или вообще любой S[_]: Foldable - но до сих пор не Seq, где вы не знаете конкретный тип.

Смежные вопросы