Idiomatische Konstruktion, um zu überprüfen, ob eine Sammlung ist bestellt

Mit der Absicht zu lernen und weiter zu diesem Frage habe ich blieb neugierig auf das idiomatische alternativen zur expliziten Rekursion für einen Algorithmus, der prüft, ob eine Liste (oder eine Sammlung) bestellt wird. (Ich bin halten die Dinge einfach, hier durch einen operator zu vergleichen und Int als Typ, ich würde gerne betrachten, die der Algorithmus vor dem eintauchen in die Generika davon)

Grundlegende rekursive version wäre (von @Luigi Plinge):

def isOrdered(l:List[Int]): Boolean = l match {
  case Nil => true
  case x :: Nil => true
  case x :: xs => x <= xs.head && isOrdered(xs)
}

Einer mangelhaften idiomatischer Weg wäre:

def isOrdered(l: List[Int]) = l == l.sorted

Einen alternativen Algorithmus mit Falten:

def isOrdered(l: List[Int]) =
  l.foldLeft((true, None:Option[Int]))((x,y) =>
    (x._1 && x._2.map(_ <= y).getOrElse(true), Some(y)))._1

Es hat den Nachteil, dass es vergleicht für alle n Elemente von der Liste, selbst wenn es aufhören könnte früher nach dem Auffinden der ersten out-of-order-element. Gibt es eine Möglichkeit, "stop" Falten und daher macht dies eine bessere Lösung?

Andere (elegante) alternativen?

  • Mit Boolean als Werte von if Aussagen macht mich traurig, und Luigi ' s version war leicht aus (erkennen umgekehrter Reihenfolge). Fixiert es für Sie.
  • Ihre "korrigierte" version gibt true zurück, auf isOrdered(List(1,2,1,2)), das ist der Grund, warum ich rollte Sie zurück, und das ist, warum ich ändern bin es wieder...
  • Feste zu beheben.
  • Es sollte angemerkt werden, dass l == l.sorted funktioniert möglicherweise nicht für Listen von Objekten, die andere als int-Werte, wenn der Sortier-Algorithmus ist nicht stabil.
InformationsquelleAutor maasg | 2011-10-21
Schreibe einen Kommentar