Как в Scala найти уникальные элементы в списке?
Как в Scala найти уникальные элементы в списке
Ответ 1
Наиболее эффективным способом сохранения порядка будет использование Set
в качестве вспомогательной структуры данных:
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)
}
Мы можем обернуть это в некотором более сильном синтаксисе, используя неявное преобразование:
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)
Ответ 2
В 2.8 это:
List(1,2,3,2,1).distinct // => List(1, 2, 3)
Ответ 3
Создайте собственный фильтр uniq с сохранением заказа:
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)
Ответ 4
Если вы ссылаетесь на Rosetta Code: создайте последовательность уникальных элементов
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)
Так как List
неизменен, вы не будете изменять начальный List
, вызывая removeDuplicates
Предупреждение: как указано этот твит (!), это не сохраняет порядок:
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)
При a Seq
этот метод должен быть доступен в Scala2.8, в соответствии с билет 929.
Тем временем вам нужно будет определить специальный статический метод в качестве который можно увидеть здесь
Ответ 5
Imho, все интерпретации вопроса ложны:
Как в Scala найти уникальные элементы в списке?
Учитывая этот список:
val ili = List (1, 2, 3, 4, 4, 3, 1, 1, 4, 1)
единственным уникальным элементом в списке является 2
. Другие предметы не уникальны.
ili.toSet.filter (i => ili.indexOf (i) == ili.lastIndexOf (i))
найдет его.
Ответ 6
Простой метод ad-hoc - это просто добавить список в набор и использовать оттуда:
val l = List(1,2,3,3,3,4,5,5,6,7,8,8,8,9,9)
val s = Set() ++ x
println(s)
Выдает:
> Set(5, 1, 6, 9, 2, 7, 3, 8, 4)
Это работает для Seq (или любого Итерабельного), но не обязательно в 2.8, где метод removeDuplicates, вероятно, будет более читабельным. Кроме того, не уверен в производительности во время выполнения и более продуманном преобразовании.
Также обратите внимание на потерянное упорядочение.
Ответ 7
list.filter { x => list.count(_ == x) == 1 }
Ответ 8
list.toSet будет делать это, поскольку Set по определению содержит только уникальные элементы