2017-02-06 2 views
2

Da ich neu bei scala bin google ich viele Dinge und finde gute Antworten in den meisten Fällen. Aber ich konnte keine Antwort auf diese spezifische Frage finden, da googeln "nach-dekrement in scala" nur nach oben bringt, nützt-nach-dekrement-in-scala-weil-es-eine-funktionale-Sprache-Antworten.Zuordnen von Ordnungszahl zu Sequenz ohne nach-Dekrement in scala

Also, ich möchte wirklich wissen, was die funktionelle Art und Weise ist zu tun, die folgenden:

object A { 
    val list = List("a", "b", "c") 
    val map = { 
    var ord = list.size 
    Map(list map { x => (x, { val res = ord; ord -= 1; res }) } : _*) 
    } 
} 

class Test extends org.scalatest.FunSuite { 
    test("") { 
    println(A.map) // Map(a -> 3, b -> 2, c -> 1) 
    } 
} 

Es ist im Grunde eine Karte aus einer vorgegebenen Liste erstellen und Ordnungszahlen der Liste zu jedem Element zuweisen abnehmend (real Code ist natürlich komplexer als dieses minimale Beispiel).

Ich bin besonders unzufrieden mit var ord = ... (veränderbar) und { val res = ord; ord -= 1; res } (Post-Dekrement) Teile:/Gibt es eine andere (schönere) Art, dies zu tun?

Antwort

2

Eine schnelle Lösung, um die Liste Umkehr erfordern würde und dann können Sie zipWithIndex verwenden:

scala> :pa 
// Entering paste mode (ctrl-D to finish) 

List("a", "b", "c") 
    .reverse 
    .zipWithIndex 
    .toMap 

// Exiting paste mode, now interpreting. 

res4: scala.collection.immutable.Map[String,Int] = Map(c -> 0, b -> 1, a -> 2) 

Wenn Sie die Zuordnungen der zusätzlichen Sammlung nicht stören s, können Sie view entfernen.

+1

Das zweite 'reverse' ist unnötig, angesichts der' toMap' –

+0

@TheArchetypalPaul stimme ich zu, aber ich wollte das Beispiel Drucken Sie es so, wie OP es sehen wollte. Vielleicht sollte ich es entfernen. –

+0

@YuvalItzchakov Ich bin mir bewusst, dass Karten nicht bestellt werden;) – Alex

0

Sie können dies einfach schreiben:

val list = List("a","b","c") 
list.map (elem => (elem, list.size - list.indexOf(elem))).toMap 

Es Sie so das Ergebnis geben:

scala.collection.immutable.Map[String,Int] = Map(a -> 3, b -> 2, c -> 1) 
+1

Scheitert, wenn zwei Elemente den gleichen Wert haben. Außerdem ist "indexOf" O (N), also ist dies unnötig langsam. –

+0

Obwohl es fair ist, ist es nicht klar, was das OP will, wenn zwei Elemente den gleichen Wert haben ... –

+0

Ich weiß, aber wie pro Ihre Frage gab ich die Lösung, aber Sie möchten eine Karte mit der gleichen Taste mehrmals erstellen? – Dhirendra

2

zip ist hilfreich für das,

list.reverse.zip(1 to list.size + 1).toMap 
+0

Sie brauchen nicht die' + 1' –

0

Versuchen Sie folgendes:

list.toIterator.zip(Iterator.iterate(list.size){_-1}).toMap 
1

Und noch eine weitere Variante

list.zip(list.size to 1 by -1).toMap 

Ähnliche in der Leistung der .reverse.zipWithIndex, weil sowohl reverse und size sind O (N)

Verwandte Themen