简体   繁体   English

Scala过滤器元组(x,y)==(y,x)

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM