Як у Scala знайти унікальні предмети у списку?
Як у Scala знайти унікальні предмети у списку?
Відповіді:
Найефективнішим способом збереження замовлень було б використання a 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.8 це:
List(1,2,3,2,1).distinct // => List(1, 2, 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)
Якщо ви звертаєтесь до Розеттського коду: Створіть послідовність унікальних елементів
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)
Для Seq
, цей метод повинен бути доступний у Scala2.8, відповідно до квитка 929 .
Тим часом вам потрібно буде визначити спеціальний статичний метод як той, який ми бачимо тут
toList
, мабуть :) Або, як запропонував @Synesso, використовуйте foldLeft
.
Імхо, всі тлумачення запитання хибні:
Як у 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))
знайде.
Простий спеціальний метод - це просто додати Список до Набору та використовувати звідти:
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 (або будь-якого Iterable), але не є необхідним у 2.8, де метод removeDuplicates, ймовірно, буде більш читабельним. Крім того, не впевнений у продуктивності виконання та більш продуманому перетворенні.
Також зверніть увагу на загублене замовлення.