Подтвердить что ты не робот

Почему Scala списки имеют порядок?

Есть ли причина, почему в 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]]

ИЗМЕНИТЬ

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

4b9b3361

Ответ 1

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

Ответ 2

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

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))

Ответ 3

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

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

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

Ответ 4

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

Ответ 5

Вы можете использовать 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
  }
})

Ответ 6

В более новых версиях 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))