Scala筛选元组列表

4

问题:如何基于列表中的其他项进行过滤?

我有一个类似于以下内容的列表:

List((2,2),(2,1),(3,1),....)

我希望保留那些在第一个数字相同的元组中,第二个数字最大的元组。
因此输出结果应该类似于这样。
List((2,2),(3,1),...)

由于1在(2,2)中小于2,因此需要删除(2,1),与此同时,我需要根据列表中的其他对象进行过滤,您如何做到这一点。

效率并不是很重要,因为列表最多包含171个项目

2个回答

16

将一组成对的列表转换为映射时,如果一个给定的“键”出现两次,则使用最后出现的条目。

而元组按第一个元素、第二个元素等排序。

因此:

List((2,2),(2,1),(3,1)).sorted.toMap
// = List((2,1),(2,2),(3,1)).toMap
// = Map((2,2), (3,1))

如果需要,只需使用.toList将其转换回列表即可。


11
for ((x, y) <- lst if !lst.exists(t => x == t._1 && y < t._2)) yield (x, y)

但是,如果你希望避免二次复杂度:

lst.groupBy(_._1).map(_._2.max).toList.sorted

你对第二个例子非常确定吗?groupBy将返回一个Map[Int,(Int,Int)]。 - Kevin Wright
3
有一天,我将不再感到惊讶,因为人们宁愿猜测,也不愿将一行代码粘贴到 REPL 中。 - psp
Extempore 是正确的做法!同样,在接受答案之前进行实际测试也是如此... - Kevin Wright
lst.groupBy(_._1) 返回的是 scala.collection.immutable.Map[Int,scala.collection.immutable.IndexedSeq[(Int, Int)]],而不是 Map[Int, (Int, Int)]。在回答之前我已经在 repl 中尝试过这两种方式了。我是不是漏掉了什么? - axel22
2
毫不留情地对待你的地图。 :D - axel22
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接