How in Scala to find unique items in List

Scala

Scala Problem Overview


How in Scala to find unique items in List?

Scala Solutions


Solution 1 - Scala

In 2.8, it's:

List(1,2,3,2,1).distinct  // => List(1, 2, 3)

Solution 2 - Scala

The most efficient order-preserving way of doing this would be to use a Set as an ancillary data structure:

def unique[A](ls: List[A]) = {
  def loop(set: Set[A], ls: List[A]): List[A] = ls match {
    case hd :: tail if set contains hd => loop(set, tail)
    case hd :: tail => hd :: loop(set + hd, tail)
    case Nil => Nil
  }

  loop(Set(), ls)
}

We can wrap this in some nicer syntax using an implicit conversion:

implicit def listToSyntax[A](ls: List[A]) = new {
  def unique = unique(ls)
}

List(1, 1, 2, 3, 4, 5, 4).unique    // => List(1, 2, 3, 4, 5)

Solution 3 - Scala

Roll your own uniq filter with order retention:

scala> val l = List(1,2,3,3,4,6,5,6)
l: List[Int] = List(1, 2, 3, 3, 4, 6, 5, 6)

scala> l.foldLeft(Nil: List[Int]) {(acc, next) => if (acc contains next) acc else next :: acc }.reverse
res0: List[Int] = List(1, 2, 3, 4, 6, 5)

Solution 4 - Scala

If you refer to the Rosetta Code: Create a Sequence of unique elements

val list = List(1,2,3,4,2,3,4,99)
val l2 = list.removeDuplicates
// l2: scala.List[scala.Int] = List(1,2,3,4,99)

Since List is immutable, you wont modify the initial List by calling removeDuplicates

Warning: as mentioned by this tweet(!), this does not preserve the order:

scala> val list = List(2,1,2,4,2,9,3)
list: List[Int] = List(2, 1, 2, 4, 2, 9, 3)

scala> val l2 = list.removeDuplicates
l2: List[Int] = List(1, 4, 2, 9, 3)

For a Seq, that method should be available in Scala2.8, according to ticket 929.
In the meantime, you will need to define an ad-hoc static method as the one seen here

Solution 5 - Scala

Imho, all the interpretations of the question are false:

> How in Scala to find unique items in List?

Given this list:

val ili = List (1, 2, 3, 4, 4, 3, 1, 1, 4, 1) 

the only unique item in the list is 2. The other items aren't unique.

ili.toSet.filter (i => ili.indexOf (i) == ili.lastIndexOf (i))

will find it.

Solution 6 - Scala

list.filter { x => list.count(_ == x) == 1 }

Solution 7 - Scala

A simple ad-hoc method is just to add the List to a Set, and use from there:

  val l = List(1,2,3,3,3,4,5,5,6,7,8,8,8,9,9)
  val s = Set() ++ x
  println(s)

Produces:

> Set(5, 1, 6, 9, 2, 7, 3, 8, 4)

This works for a Seq (or any Iterable), but is not necessary in 2.8, where the removeDuplicates method will probably be more readable. Also, not sure about the runtime performance vs a more thought-out conversion.

Also, note the lost ordering.

Solution 8 - Scala

list.toSet will do it since Set by definition only contains unique elements

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionVolodymyr BezuglyyView Question on Stackoverflow
Solution 1 - ScalajamesqiuView Answer on Stackoverflow
Solution 2 - ScalaDaniel SpiewakView Answer on Stackoverflow
Solution 3 - ScalaSynessoView Answer on Stackoverflow
Solution 4 - ScalaVonCView Answer on Stackoverflow
Solution 5 - Scalauser unknownView Answer on Stackoverflow
Solution 6 - ScalasloucView Answer on Stackoverflow
Solution 7 - ScalaMitch BlevinsView Answer on Stackoverflow
Solution 8 - ScalaMuriloView Answer on Stackoverflow