在scala中对case class字段进行动态分组

时间:2018-07-15 11:22:26

标签: scala dynamic grouping case-class

如何对以案例类作为字段的案例类列表执行groupBy操作? 例如:

case class F1(str1:Option[String],str2:Option[String])
case class F2(int1:Option[Int],int2:Option[Int])

case class Parent(str:F1, int:F2)

假设我有一个案例类Parent的列表,并且我必须动态地对任何子案例类字段执行groupBy。

val data = List(Parent(F1(Some("abc"), Some("pqr"))), F2(Some(20), Some(30)))
                Parent(F1(Some("abc"), Some("xyz"))), F2(Some(20), Some(30)))
                Parent(F1(Some("def"), Some("pqr"))), F2(None, Some(30)))
                Parent(F1(Some("def"), Some("pqr"))), F2(Some(20), Some(30)))
                Parent(F1(None, Some("xyz"))), F2(None, Some(30))))

我要执行data.groupBy("str1"),其中“ str1”是大小写F1的字段名称,并将动态传递。

如果此操作成功执行,则输出为:

Map(Some("abc") -> List(Parent(F1(Some("abc"), Some("pqr"))), F2(Some(20), Some(30))),
                        Parent(F1(Some("abc"), Some("xyz"))), F2(Some(20), Some(30)))),
    Some("def") -> List(Parent(F1(Some("def"), Some("pqr"))), F2(None, Some(30))),
                        Parent(F1(Some("def"), Some("pqr"))), F2(Some(20), Some(30)))),
    None        -> List(Parent(F1(None, Some("xyz"))), F2(None, Some(30))))) 

1 个答案:

答案 0 :(得分:3)

对于List[+A],groupBy具有签名

def groupBy[K](f: (A) ⇒ K): Map[K, List[A]]

对于您来说,AParent,因此您可以使用

data.groupBy(_.str.str1)

这里.str映射到F1,然后.str1映射到您要分组的Option[String]

尤其是,我们将A => K传递给groupBy而不是值。如果您尝试传递(类似)字符串,例如(_ => "str1")归为groupBy,它将在分组时将所有内容映射到该字符串,因此所有内容最终都将归入同一组,而您只有Map("str1" -> data)

关于动态传递"str1",您可以传递_.str.str1