Почему в списках Scala нет порядка? - PullRequest
21 голосов
/ 20 декабря 2010

Есть ли причина, по которой в Scala нет неявного упорядочивания списков?

val lists = List(List(2, 3, 1), List(2, 1, 3))
lists.sorted

error: could not find implicit value for parameter ord: Ordering[List[Int]]

РЕДАКТИРОВАТЬ

Да, мой вопрос: почему нет встроенных-в порядке, который уже неявно в области.Мне кажется очевидным, что второй список должен быть «меньше» первого списка, так как элементы в 0 равны, а во втором списке есть нижний элемент в 1. Мне было интересно, может быть, нет хорошего ответа, когдаСписки двух разных размеров.

Ответы [ 6 ]

44 голосов
/ 21 декабря 2010

Я думаю, что это упущение.Лексикографический порядок имеет смысл на Seqs.Мы должны добавить его в стандартную библиотеку.

7 голосов
/ 21 декабря 2010

Кстати, даже до того, как я это исправил, вы могли бы сделать это другими способами:

scala> List[Iterable[Int]](List(2, 3, 1), List(2, 1, 3)).sorted
res0: List[Iterable[Int]] = List(List(2, 1, 3), List(2, 3, 1))

scala> List(List(2, 3, 1), List(2, 1, 3)).sorted(Ordering[Iterable[Int]])
res1: List[List[Int]] = List(List(2, 1, 3), List(2, 3, 1))

Но теперь это работает так, как вы надеетесь.

Редактировать: из-за отрывочных проблем с расхождением снеявно я переместил его из области по умолчанию.Наличие неявного преобразования, которое действует через границы:

implicit def SeqDerived[CC[X] <: collection.Seq[X], T](implicit ord: Ordering[T]): Ordering[CC[T]]

... - это потенциальный рецепт для проблем.Он будет доступен в версии 2.9, но вы должны импортировать его следующим образом.

scala> val lists = List(List(2, 3, 1), List(2, 1, 3))
lists: List[List[Int]] = List(List(2, 3, 1), List(2, 1, 3))

scala> lists.sorted
<console>:9: error: could not find implicit value for parameter ord: Ordering[List[Int]]
       lists.sorted
             ^

scala> import Ordering.Implicits._
import Ordering.Implicits._

scala> lists.sorted
res1: List[List[Int]] = List(List(2, 1, 3), List(2, 3, 1))
4 голосов
/ 20 декабря 2010

Единственный действительно разумный общий порядок в классе List [Int] будет лексикографическим (т. Е. Сравнивать первые элементы списка, затем вторые, если они равны, третьи, если секунды равны, и т. Д.),Это не предусмотрено стандартной библиотекой, вероятно, потому что не так много случаев, когда это действительно необходимо.Было бы достаточно легко создать неявное преобразование из List [X] в Ordering [List [X]], которое бы это реализовало, и тогда вы могли бы просто импортировать это преобразование, где бы оно вам ни понадобилось.

4 голосов
/ 20 декабря 2010

У вас есть список списков, а не список целых чисел. То, что вам не хватает, является критерием для определения, является ли список <= другим списком или нет. </p>

Вот что говорится в сообщении об ошибке: я не могу найти способ сравнить список с другим списком, вы должны предоставить его явно.

Если ваш вопрос был «почему у списка нет встроенного метода сравнения с другими списками», ну, это просто так.

1 голос
/ 20 декабря 2010

Вы можете использовать sortWith. Это не учитывает списки разного размера, потому что zip выбросит разницу, но я думаю, что это что-то вроде того, что вы ищете:

lists.sortWith((a,b) => {
  a.zip(b).filterNot(x => x._1 == x._2) match {
    case Nil => true
    case t => t._1 < t._2
  }
})
0 голосов
/ 24 января 2019

В более новых версиях Scala (протестировано с 2.12.5) есть Порядок для Iterable [A] .Просто назначьте правильный тип вашей переменной lists:

scala> val lists = List(List(2, 3, 1), List(2, 1, 3))
lists: List[List[Int]] = List(List(2, 3, 1), List(2, 1, 3))

scala> (lists: List[Iterable[Int]]).sorted
res0: List[Iterable[Int]] = List(List(2, 1, 3), List(2, 3, 1))

Или конвертируйте элементы в экземпляры Iterable[] (что запрещено для экземпляров List[]):

scala> lists.map(_.toIterable).sorted
res1: List[Iterable[Int]] = List(List(2, 1, 3), List(2, 3, 1))
...