2010-12-20 17 views
20

Czy istnieje powód, dla którego nie ma ukrytego Zamawiania list w Scali?Dlaczego listy Scala nie mają zamawiania?

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

EDIT

Tak, moje pytanie brzmi: dlaczego nie ma wbudowanej zamówienia, które już w sposób dorozumiany w zakresie. Dla mnie wydaje się oczywiste, że druga lista powinna być "mniejsza niż" pierwsza lista, ponieważ pozycje w punkcie 0 są równe, a druga lista ma niższą pozycję w 1. Zastanawiam się, czy może to, że nie ma dobrej odpowiedzi, gdy Listy mają dwa różne rozmiary.

+2

Porządek leksykograficzny (który opisujesz) jest definiowalny dla list o różnej wielkości, chociaż musisz wybrać, czy krótsze listy są dłuższe, czy dłuższe. Oba sposoby mogą być używane do tworzenia poprawnych matematycznie zamówień, a im krótsza opcja dłuższa opcja ma również zastosowanie. To może być powód, dla którego nie ma domyślnego uporządkowania zawartego w Listach w standardowej bibliotece, ale nadal zakładam, że brak ogólnej użyteczności jest bardziej prawdopodobną przyczyną. –

Odpowiedz

42

myślę, że to niedopatrzenie. Kolejność Leksykografii ma sens w Seqs. Powinniśmy dodać go do standardowej biblioteki.

+1

Dzięki! Widzę, że wychowałeś tracker: http: // lampsvn.epfl.ch/trac/scala/ticket/4097 –

+0

Co jest domyślne, jeśli typ elementu nie ma "Zamawiania" lub "Zamówione"? – Raphael

+0

Jakieś postępy z dodawaniem do standardowej biblioteki? – user222202

4

To, co masz, to lista list, a nie lista liczb całkowitych. To, czego brakuje, to kryteria określające, czy lista to < = inna lista, czy też nie.

Oto, co mówi komunikat o błędzie: Nie mogę znaleźć sposobu na porównanie listy z inną, należy ją wyraźnie podać.

Jeśli twoje pytanie brzmiało "dlaczego lista nie ma wbudowanej metody porównywania z innymi listami", to tak właśnie jest.

+0

Myślę, że jego pytanie brzmi: dlaczego nie ma żadnych niejawnych kryteriów określania, czy lista jest <= inną listą. –

4

Jedynym sensownym łącznym porządkiem w stosunku do klasy listy [Int] byłaby leksykograficzna (tj. Porównanie pierwszych elementów listy, następnie druga, jeśli są równe, trzecia, jeśli sekundy są równe itd.). Nie jest to zapewniane przez bibliotekę standardową, prawdopodobnie dlatego, że nie ma tak wielu przypadków, w których jest to rzeczywiście potrzebne. Łatwo byłoby stworzyć niejawną konwersję z Listy [X] na Kolejność [Lista [X]], która by to zaimplementowała, a następnie po prostu zaimportować tę konwersję tam, gdzie jej potrzebujesz.

1

Możesz użyć sortWith. To nie bierze różnej wielkości list pod uwagę ze względu na suwak będzie wyrzucić różnicę, ale myślę, że robi coś, co jesteś po:

lists.sortWith((a,b) => { 
    a.zip(b).filterNot(x => x._1 == x._2) match { 
    case Nil => true 
    case t => t._1 < t._2 
    } 
}) 
7

Nawiasem mówiąc, zanim jeszcze stała to można zrobić to inne sposoby:

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

Ale teraz działa jak chcesz nadzieję.

Edycja: ze względu na problematykę rozbieżności szkicu z wymaganym niejawnym przeniosłem ją poza zakres domyślny. Mając niejawną konwersję, która działa w taki sposób:

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

... to potencjalna recepta na problemy. Będzie dostępny w wersji 2.9, ale musisz go zaimportować w następujący sposób.

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)) 
Powiązane problemy