Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Tuples duplicate elimination from a list

Consider the following list of tuples:

val input= List((A,B), 
                (C,B), 
                (B,A)) 

and assuming that the elements (A,B) and (B,A) are the same and therefore are duplicates, what is the efficient way (preferably in Scala) to eliminate duplicates from the list above. That means the desired output is an another list:

val deduplicated= List((A,B), 
                       (C,B)) 

Thanks in advance!

p.s: this is not a home work ;)

UPDATE:

Thanks to all! The "set"-solution seems to be the preferable one.

like image 816
Alice Avatar asked Feb 12 '23 11:02

Alice


1 Answers

You could try it with a set, but you need to declare your own tuple class to make it work.

case class MyTuple[A](t: (A, A)) {
  override def hashCode = t._1.hashCode + t._2.hashCode
  override def equals(other: Any) = other match {
    case MyTuple((a, b)) => a.equals(t._1) && b.equals(t._2) || a.equals(t._2) && b.equals(t._1)
    case _ => false
  }
}

val input= List(("A","B"), 
                ("C","B"), 
                ("B","A"))

val output = input.map(MyTuple.apply).toSet.toList.map((mt: MyTuple[String]) => mt.t)
println(output)

edit: Travis's answer made me realise that there is a nicer way to do this. And that is by writing a distinctBy method that works analog to sortBy.

implicit class extList[T](list: List[T]) {
  def distinctBy[U](f: T => U): List[T] = {
    var set = Set.empty[U]
    var result = List.empty[T]
    for(t <- list) {
      val u = f(t)
      if(!set(u)) {
        result ::= t
        set += u
      }
    }
    result.reverse
  }
}

println(input.distinctBy { case (a, b) => Set((a,b), (b,a)) })
like image 50
SpiderPig Avatar answered Feb 15 '23 09:02

SpiderPig