将列表列表展平为scala中具有异常的集合

时间:2014-12-31 05:49:39

标签: scala functional-programming nested-lists

这感觉就像一个特殊的问题,我对Scala很新,所以我不知道如何提出正确的问题以便在这个问题上取得进展。

作为演示,请说我有一个这样的列表列表:

val data = List(List(1, 2, 3, 4), List(1, 2, 2, 3, 4), List(1, 2, 3, 3, 3, 4), List(1, 2, 3, 4), List(2, 3, 4))

我希望能够将它减少到整数列表,这些整数看起来大多是多个列表的一组不同,但有一个例外:每个列表中每个整数都有多个,我想表示在最后的名单中。因此,作为一般规则,具有该整数的最多表示的列表将在最终列表中具有该“整数”的“重复”。所以理想情况下会给出:

List(1, 2, 2, 3, 3, 3, 4)

我知道我可以做data.flatten.distinct并获得:

List(1, 2, 3, 4)

但这不是我想要的,我知道可能需要做更多工作才能达到预期效果。

我想知道是否有一种很好的方法可以在scala中以功能方式实现所需的结果。

2 个答案:

答案 0 :(得分:4)

试试这个

val data = List(List(1, 2, 3, 4), List(1, 2, 2, 3, 4), List(1, 2, 3, 3, 3, 4), List(1, 2, 3, 4), List(2, 3, 4))

val map = data.map(_.groupBy(identity)).foldLeft(Map[Int, List[Int]]()) {
   case (r, c) => r ++ c.map {
       case (k, v) => k -> (if (v.size > r.getOrElse(k, List()).size) v else r(k))
}
}.values.flatten                               
//> map  : Iterable[Int] = List(2, 2, 4, 1, 3, 3, 3)

它不保持订购。在此之后,您可以打电话对此进行排序。

也许这更干净

data.flatMap(_.groupBy(identity)).groupBy(_._1).mapValues(_.sortBy(_._2.size).reverse(0)._2).values.flatten
//> res0: Iterable[Int] = List(2, 2, 4, 1, 3, 3, 3)

答案 1 :(得分:0)

我不太明白,但你可以订购元素

data.flatten.sorted

哪会给你

List(1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4)

如果你想按遭遇次数排序,你可以这样做:

data.flatten.groupBy(k => k).mapValues(_.size).toList.sortBy(_._2).map(_._1)

会给你

List(1, 4, 2, 3)