2017-07-27 4 views
2

私のアプリケーションでは、タプルのリストを取得する必要がある場所がたくさんあります。タプルの最初の要素でgroupByし、それを残りの部分から削除します。例えば、私はタプルはScala。さまざまなアリティを持つタプルを受け入れる一般的なメソッドを作成する方法は?

(1, "Joe", "Account"), (1, "Tom", "Employer"), (2, "John", "Account"), and result should be Map(1 -> List(("Joe", "Account"), ("Joe", "Account")), 2 -> List(("John", "Account"))) 

それは簡単

data.groupBy(_._1).map { case (k, v) => k -> v.map(f => (f._2, f._3)) } 

として実装されてきた。しかし、私は別のアリティを持つタプル、2、3、4、あるいは7を持つことができるので、私は、一般的な解決策を探しています。 私は型崩れ考えたりScalazは私を助けることができますが、私の経験は、これらのライブラリが低く、いくつかの例

答えて

6

にポイントしてください。この簡単に使用して実装されてshapeless(簡単にするために、私はすべてのコレクション型のためにそれを一般化されることはありません) 。

val data = 
    List((1, "Joe", "Account"), (1, "Tom", "Employer"), (2, "John", "Account")) 

assert { 
    groupTail(data) == Map(
    1 -> List(("Joe", "Account"), ("Tom", "Employer")), 
    2 -> List(("John", "Account")) 
) 
} 

としてだけでなく、さまざまな種類のTuple4のために:

val data2 = List((1, 1, "a", 'a), (1, 2, "b", 'b), (2, 1, "a", 'b)) 

assert { 
    groupTail(data2) == Map(
    1 -> List((1, "a", 'a), (2, "b", 'b)), 
    2 -> List((1, "a", 'b)) 
) 
} 
頭と尾にそれらを分解することができタプルのための特定の型クラスは、これはあなたのケースのために働く IsComposite

import shapeless.ops.tuple.IsComposite 

def groupTail[P, H, T](tuples: List[P])(
    implicit ic: IsComposite.Aux[P, H, T]): Map[H, List[T]] = { 
    tuples 
     .groupBy(ic.head) 
     .map { case (k, vs) => (k, vs.map(ic.tail)) } 
} 

が呼ばれています

実行可能コードが利用可能ですat Scastie

+1

ありがとう、オレグ。それは私が望んだものです –

関連する問題