说我有一个如下列表:
val l = List( (1, 2, "hi"), (1, 3, "hello"), (2, 3, "world"), (1, 2, "hello") )
我想使l
的元素明显忽略元组的第3个元素。也就是说,l
的两个元素如果它们的前两个元素相同则被认为是相同的。
所以makeDistinct(l)
应该返回
List( (1, 2, "hi"), (1, 3, "hello"), (2, 3, "world") )
实施makeDistinct
编辑:我们可以自由选择要删除的内容,并且无需保留订购。
答案 0 :(得分:3)
如果您想对列表执行此操作,请使用groupBy
:
l.groupBy(x => (x._1, x._2)).map(kv => kv._2.head).toList
如果你真的想要对所有集合类型都是通用的:
scala> import scala.collection.generic.CanBuildFrom
import scala.collection.generic.CanBuildFrom
scala> def distinct[A, B, C, CC[X] <: Traversable[X]](xs: CC[(A, B, C)])(implicit cbf: CanBuildFrom[Nothing, (A, B, C), CC[(A, B, C)]]): CC[(A, B, C)] = xs.groupBy(x => (x._1, x._2)).map(kv => kv._2.head).to[CC]
warning: there were 1 feature warnings; re-run with -feature for details
distinct: [A, B, C, CC[X] <: Traversable[X]](xs: CC[(A, B, C)])(implicit cbf: scala.collection.generic.CanBuildFrom[Nothing,(A, B, C),CC[(A, B, C)]])CC[(A, B, C)]
scala> distinct(List((1, 2, "ok"), (1, 3, "ee"), (1, 2, "notok")))
res0: List[(Int, Int, String)] = List((1,3,ee), (1,2,ok))
答案 1 :(得分:1)
您可以使用Ordering
:
scala> SortedSet(l: _*)(Ordering[(Int, Int)].on(x => (x._1, x._2))).toList
res33: List[(Int, Int, String)] = List((1,2,hello), (1,3,hello), (2,3,world))
唯一的问题是保留了最后找到的元素。对于第一个,您需要反转列表:
scala> SortedSet(l.reverse: _*)(Ordering[(Int, Int)].on(x => (x._1, x._2))).toList
res34: List[(Int, Int, String)] = List((1,2,hi), (1,3,hello), (2,3,world))
反过来并不是最优的,但也许可以按相反的顺序直接创建列表,这样可以避免构建不必要的中间列表。