[英]Scala filter tuples (x, y) == (y, x)
I have a list of tuples, for example: 我有一个元组列表,例如:
(0,2)
(0,5)
(2,0)
(2,5)
(3,4)
(4,3)
(5,0)
(5,2)
There are some tuples where (x, y) == (y, x)
, for example (5, 0) and (0, 5). 有一些元组,其中
(x, y) == (y, x)
,例如(5,0)和(0,5)。 I want to leave just one of them, for example first one. 我只想离开其中一个,例如第一个。 How can I do it?
我该怎么做?
Using foldLeft 使用foldLeft
var ts = List((0,2), (0,5), (2,0), (2,5), (3,4), (4,3), (5,0), (5,2))
ts.foldLeft(List[(Int,Int)]())
{(acc, el) => if ((acc contains el) || (acc contains el.swap)) acc else el::acc}
// List[(Int, Int)] = List((3,4), (2,5), (0,5), (0,2))
Or, with Sets for an O(n) version (assuming Set lookup and additions are O(1)) 或者,使用O(n)版本的Set(假设Set的查找和添加为O(1))
ts.foldLeft(Set[(Int,Int)]()){(acc, el) => if (acc(el.swap)) acc else acc + el}
If it doesn't matter if we re-order ones where the swapped tuple is not present (I'm guessing it doesn't as you don't specify which of the ones that have a swapped tuple should be kept): 如果我们重新排序不存在已替换的元组的那些(如果您没有指定应保留哪些具有已替换的元组的那些,则不然),则无所谓:
ts.map{t => if (t._1 < t._2) t else t.swap}.distinct
// List[(Int, Int)] = List((0,2), (0,5), (2,5), (3,4))
You can groupBy
the tuples represented as a Set
, which will make Set(0, 5) == Set(5, 0)
, etc. Then map
the resulting Map
to the groups of tuples and convert it back to a List
, and finally grab the head
of each list for one representative of the group. 您可以
groupBy
表示为一个元组Set
,这将使得Set(0, 5) == Set(5, 0)
等,然后map
生成的Map
到元组的团体和将其转换回一个List
,最后抢head
每个列表的一个代表组。 Calling head
is ok here, because the groups will never be empty (they would otherwise just not be there at all). 在这里调用
head
是可以的,因为组永远不会为空(否则它们将根本不存在)。
val list = List((0,2), (0,5), (2,0), (2,5), (3,4), (4,3), (5,0), (5,2))
list.groupBy { case (x, y) => Set(x, y) } // Map[Set, List[(Set, (Int, Int))]]
.map(_._2) // Iterable[List[(Int, Int)]]
.toList // List[List[(Int, Int)]]
.map(_.head) // List[(Int, Int)]
res10: List[(Int, Int)] = List((0,5), (3,4), (2,5), (0,2))
How about first sorting the tuple pairs internally. 首先对内部的元组对进行排序怎么样? I believe this technique would pass through your list just twice since distinct is advertised as O(n) complexity:
我相信这项技术只会通过您的列表两次,因为区别在于O(n)的复杂性:
val ts = List((0,2),(0,5),(2,0),(2,5),(3,4),(4,3),(5,0),(5,2))
ts.map{ case (x,y) if x < y => (y,x) case (x,y) => (x,y) }.distinct
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.