Scala - Suche nach einem bestimmten Tupel in einer Liste
Ich bin schlug meinen Kopf an die Wand, über diese ein. (zur info, ich bin nicht eine scala pro noch nicht, aber ich Liebe es big time)
Sagen wir, wir haben diese Liste von Tupeln:
val data = List(('a', List(1, 0)), ('b', List(1, 1)), ('c', List(0)))
Der Liste hat diese Signatur:
List[(Char, List[Int])]
Meine Aufgabe ist es, um die "List[Int] - element aus einem Tupel innerhalb von "Daten", deren Schlüssel ist, lassen Sie uns zum Beispiel sagen, der Buchstabe "b".
In anderen Worten, wenn ich implementieren Sie eine Methode wie "findIntList(Daten, 'b')", dann erwarte ich ein Ergebnis-Liste(1, 1)
Nur um das Bild zu vervollständigen, habe ich versucht, die folgenden Ansätze. Das problem ist, dass mit den Ansätzen (ausser Methode 1, die ich beschäftigen ein explizites "return"), ich erhalte entweder eine List[Option]
oder List[Any]
- Objekt zurück, das weiß ich nicht, wie das extrahieren der "List[Int]
" Informationen aus
Ansatz 1:
data.foreach { elem => if (elem._1 == char) return elem._2 }
Ansatz 2:
data.find(x=> x._1 == ch)
Ansatz 3:
for (elem <- data) yield elem match {case (x, y: List[Bit]) => if (x == char) y}
Ansatz 4:
for (x <- data) yield if (x._1 == char) x._2
Option(char, List[Bit])
wie das, was Ihr aus data.find
, Sie können Holen Sie sich die aktuellen Tupel mit .get
: der Nachteil ist, dass es wird eine exception werfen wenn nichts gefunden wurde. Für was es Wert ist, diese Aufgabe schrieb ich meine eigene Funktion als higher-order-Listen-Funktionen sind erst in Woche 5.(coursera.org/course/progfun)
Dank Mark! Die .bekommen, ist die Magie hier
Wenn Sie ein element vom Typ Option[T]" Sie können es durch eine Karte/foreach/filter, etc... Das funktioniert wie ein ganz netter Abstraktion über "null"
sollten Sie sich akzeptieren Antworten, die Ihr problem lösen. Klicken Sie einfach auf das Häkchen neben der Option die Antwort. Wenn Sie nicht akzeptieren, Antworten auf zu viele Fragen, die Menschen werden aufhören, Ihre Fragen beantworten.
InformationsquelleAutor mainas | 2013-04-25
Du musst angemeldet sein, um einen Kommentar abzugeben.
Nur eine von vielen Möglichkeiten:
toMap
wandelt eine Liste von 2-Tupeln in einerMap
aus das erste element der Tupel das zweite.get
gibt Sie den Wert für den angegebenen Schlüssel und gibt einOption
, so benötigen Sie ein weiteresget
eigentlich auf der Liste.Oder Sie verwenden können:
Hinweis: verwenden Sie Nur bekommen auf
Option
wenn Sie garantieren können, dass Sie eineSome
und nicht einNone
. Sehen http://www.scala-lang.org/api/current/index.html#scala.Option für wie zu verwenden Sie die Option Sprache.Update: Erläuterung der Ergebnis-Typen, die Sie sehen mit Ihren verschiedenen Ansätzen
Ansatz 2: finden Sie gibt eine Option[List[Int]], denn es können nicht garantieren, dass ein übereinstimmendes element gefunden wird.
Ansatz 3: hier können Sie im Grunde tun, eine
map
, D. H. Sie wenden eine Funktion auf jedes element der collection. Für das element, das Sie suchen, liefert die Funktion Ihre List[Int], die für alle anderen Elemente, die es enthält den Wert()
ist dieUnit
Wert, das entspricht rundvoid
in Java, sondern eine echte type. Da der einzige gemeinsame super-Typ List[Int] und die Einheit ist Alle Sie bekommen eine List[Any] als Ergebnis.Ansatz 4 ist im Grunde das gleiche wie #3
get
auf eine unbekannte option, wenn eine NoSuchElementException wäre die richtige exception zu werfen?Ich würde werfen, dass Ausnahme schlechter Stil (und sicherlich nicht idiomatischen). Also ich denke, wenn Sie implementieren eine API, die bestimmt, dieses Verhalten, und was Sie nicht ändern können, es wäre ok. Andernfalls ändern Sie die API, um eine Option oder eine Versuchen (scala-lang.org/archives/downloads/distrib/files/nightly/docs/...), oder wenn Sie wie Scalaz ist eine Validierung (blog.lunatech.com/2012/03/02/validation-scala)
Daten.find(_._1 = = "b").bekommen._2 ------- ich Liebe genius! Dank Jens. Es funktioniert
Ok, ich weiß, ich habe nicht gründlich recherchiert noch, so dass es offensichtlich ist, ich bin schneiden Ecken hier 🙂 . Aber ich Frage mich nur, mit die mehrere Ansätze, die ich verwendet, warum manche geben zurück Liste[Option] und andere List[Any]?
Vereinbart. Der Kontext hier ist eine Zuordnung auf die Huffman-Codierung, wo die
List(Char, List[Bit])
aufgebaut ist, um alle Zeichen, die Sie versuchen zu codieren. Es wäre sicherlich eine Programmierung/Korrektheit-Fehler, wenn die encoding-Tabelle, die Sie gerade aufgebaut hat nicht alle der Zeichen in der Zeichenfolge, die Sie versuchen zu codieren. Aber dann so etwas wie eineAssertionFailedError
wäre wahrscheinlich besser.InformationsquelleAutor Jens Schauder
Andere Möglichkeit ist
Oder mit einem Zwischenschritt das ist noch schöner:
wo
apply
verwendet wird, implizit, d.h., die Letzte Zeile ist äquivalent zuIch denke, dies ist aufgrund
toMap
mit einem impliziten argument.InformationsquelleAutor chris
Gibt es mehrere Möglichkeiten, es zu tun. Eine weitere Möglichkeit:
InformationsquelleAutor Jatin
Können Sie versuchen, so etwas wie(wenn Sie sicher sind, dass er existiert), indem Sie einfach Informationen eingeben.
oder verwenden Sie
headOption
wenn Ihr nicht sicher, ob das Zeichen existiertInformationsquelleAutor korefn
Können Sie auch lösen, diese mit pattern-matching. Halten Sie im Verstand, den Sie brauchen, um es zu rekursiven obwohl. Die Lösung sollte etwa so Aussehen;
Was wird dies tun, ist zu Fuß Ihre Tupel-Liste rekursiv. Prüfen Sie, ob das head-element entspricht der Bedingung (der Schlüssel, den Sie suchen) und dann gibt es zurück. Oder weiterhin mit dem Rest der Liste.
InformationsquelleAutor M Donkers