How in Scala to find unique items in List?
8 Answers
In 2.8, it's:
List(1,2,3,2,1).distinct // => List(1, 2, 3)

- 4,920
- 1
- 22
- 50

- 2,231
- 2
- 13
- 2
-
1Imho, 1 and 2 aren't unique items in the list. Only the 3 is. You create a list of unique items from the list, which is a different thing. – user unknown May 11 '12 at 20:02
-
19If that's what you want (it's usually not), go with: List(1,2,3,2,1).groupBy(x=>x).filter(_._2.lengthCompare(1) == 0).keySet – moveaway00 Jul 03 '13 at 15:56
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)

- 54,515
- 14
- 108
- 120
-
15It is overcomplicated *now*. Scala 2.7 didn't have anything better. – Daniel Spiewak Jul 13 '11 at 14:00
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)

- 37,610
- 35
- 136
- 207
-
4I actually enjoyed this one very much, as it allows complex filtering logic. Thanks! – BorisOkunskiy Oct 24 '11 at 13:20
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

- 1,262,500
- 529
- 4,410
- 5,250
-
-
Call `toList`, apparently :) Or, as proposed by @Synesso, use `foldLeft`. – BorisOkunskiy Oct 24 '11 at 13:22
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.

- 35,537
- 11
- 75
- 121
-
4most java/scala devs would translate a question of "unique items in a given list" as "all distinct values with a given list" not "all values showing up singularly within a given list"... which is how every answer before yours interpreted it, as well as the person asking the question (who approved such an answer). what does coming in 2+ years later and being extra sensitive on the parsing of an already answered question add? – mujimu Jul 02 '12 at 20:04
-
1@mujimu: I don't remember why I stumbled over the question 2 years later. Maybe sombebody closed a similar question as exact duplicate and linked here. Often I try to answer such questions for myself as an exercise before looking for the solutions of others; whether they have a similar or a better solution or whether it makes sense to publish mine. So I found that the others answered a different question. After knowing how others understood the question differently I still think that the terminology is wrong. The meaning of a sentence shouldn't be judged by majority. – user unknown Jul 03 '12 at 10:13
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.

- 13,186
- 3
- 44
- 32
list.toSet will do it since Set by definition only contains unique elements

- 1
-
2This was pointed out, in a previous answer, over 5 years ago, What's your point? – jwvh Feb 20 '17 at 05:28