Scala group By First Occurrence

时间:2016-11-08 14:45:52

标签: scala group-by

我有以下数据:

List(Map("weight"->"1000","type"->"abc","match"->"first"),Ma‌​p("weight"->"1000","‌​type"->"abc","match"‌​->"third"),Map("weig‌​ht"->"182","type"->"‌​bcd","match"->"secon‌​d"),Map("weight"->"1‌​50","type"->"bcd","m‌​atch"->"fourth"),Map‌​("weight"->"40","typ‌​e"->"aaa","match"->"‌​fifth"))

按"分组"我想要第一个结果" abc"然后" bcd"然后" aaa"

当我按&#34键入组时,输入"结果映射给出第一个键为aaa,而我希望第一个键为" abc"和所有相应的值。

我怎样才能做到这一点?

2 个答案:

答案 0 :(得分:1)

如评论中所述,您需要一个有序的地图,它不是由一个简单的小组创建的。你能做的是:

val a = List(Map("weight"->"1000", "type"->"abc","match"->"first"), Map("weight"->"1000","type"->"abc","match"->"third"),Map("weig‌​ht"->"182","type"->"‌​bcd","match"->"secon‌​d"), Map("weight"->"1‌​50","type"->"bcd","m‌​atch"->"fourth"), Map("weight"->"40","type"->"aaa","match"->"‌​fifth"))
val sortedGrouping = SortedMap.empty[String,String] ++ a.groupBy { x => x("type") }
println(sortedGrouping)

你得到(打印)的是:

Map(aaa -> List(Map(weight -> 40, type -> aaa, match -> ‌​fifth)), abc -> List(Map(weight -> 1000, type -> abc, match -> first), Map(weight -> 1000, type -> abc, match -> third)), bcd -> List(Map(weight -> 1‌​50, type -> bcd, m‌​atch -> fourth)), ‌​bcd -> List(Map(weig‌​ht -> 182, type -> ‌​bcd, match -> secon‌​d)))

答案 1 :(得分:0)

我认为没有开箱即用的解决方案可以实现您的目标。 Map有两种使用方式:通过键获取值,然后迭代它。第一部分不受排序顺序的影响,因此groupBy非常有效。第二部分可以通过按所需顺序创建密钥列表,然后使用该列表以特定顺序从Map获取键值对来实现。例如:

val xs = List(Map("weight"->"1000","type"->"abc","match"->"first"),
              Map("weight"->"1000","type"->"abc","match"->"third"),
              Map("weight"->"182","type"->"bcd","match"->"second"),
              Map("weight"->"150","type"->"bcd","match"->"fourth"),
              Map("weight"->"40","type"->"aaa","match"->"‌fifth"))

import collection.mutable.{ListBuffer, Set}

// List of types in the order of appearance in your list 
val sortedKeys = xs.map(_("type")).distinct

//> sortedKeys: List[String] = List(abc, bcd, aaa)

现在,当您需要迭代时,只需执行:

val grouped = xs.groupBy(_("type"))

sortedKeys.map(k => (k, grouped(k)))
//  List[(String, List[scala.collection.immutable.Map[String,String]])] =
//  List(
//    (abc,List(Map(weight -> 1000, type -> abc, match -> first),
//              Map(weight -> 1000, type -> abc, match -> third))),
//    (bcd,List(Map(weight -> 182, type -> bcd, match -> second),
//              Map(weight -> 150, type -> bcd, match -> fourth))),
//    (aaa,List(Map(weight -> 40, type -> aaa, match -> ‌fifth)))
//  )