2009-07-16 19 views

Antwort

21

Es ist nicht klar, wonach Sie fragen - was Sie erwarten, dass die Semantik des multiplen Ertrags ist. Eine Sache ist jedoch, dass Sie wahrscheinlich nie Indizes verwenden möchten, um durch eine Liste zu navigieren - jeder Aufruf von t (i) ist O (i) zur Ausführung.

hier ist also eine Möglichkeit, dass Sie für

scala> val l = List(1,2,3); val t = List(-1,-2,-3) 
l: List[Int] = List(1, 2, 3) 
t: List[Int] = List(-1, -2, -3) 

scala> val pairs = l zip t 
pairs: List[(Int, Int)] = List((1,-1), (2,-2), (3,-3)) 

fragen könnte Und hier ist eine andere Möglichkeit, dass Sie

scala> val crossProduct = for (x <- l; y <- t) yield (x,y) 
crossProduct: List[(Int, Int)] = List((1,-1), (1,-2), (1,-3), (2,-1), (2,-2), (2,-3), (3,-1), (3,-2), (3,-3)) 

Die später zu fragen, könnte nur syntaktischer Zucker ist für

scala> val crossProduct2 = l flatMap {x => t map {y => (x,y)}} 
crossProduct2: List[(Int, Int)] = List((1,-1), (1,-2), (1,-3), (2,-1), (2,-2), (2,-3), (3,-1), (3,-2), (3,-3)) 

Eine dritte Möglichkeit ist es, sie zu verschachteln

scala> val interleaved = for ((x,y) <- l zip t; r <- List(x,y)) yield r 
interleaved: List[Int] = List(1, -1, 2, -2, 3, -3, 4, -4, 5, -5, 6, -6, 7, -7, 8, -8, 9, -9, 10, -10) 

Das für Syntax Zucker ist

scala> val interleaved2 = l zip t flatMap {case (x,y) => List(x,y)} 
interleaved2: List[Int] = List(1, -1, 2, -2, 3, -3, 4, -4, 5, -5, 6, -6, 7, -7, 8, -8, 9, -9, 10, -10) 
+0

Ich denke, er will nur die Listen interpolieren. –

+0

richtig, ich wollte sie verschachteln, so dass beide das gleiche Ergebnis liefern: [James] val verschachtelt = für ((x, y) <- l zip t; r <- Liste (x, y)) Ausbeute r [Daniel] für (i <- 0 bis 10; r <- Liste (l (i), t (i))) Ausbeute r denke ich James' eine elegantere und es gibt auch Liste . Vielen Dank Jungs. –

0

Anscheinend nicht. Ich bekomme einen Kompilierfehler, wenn ich es versuche.

Es sieht aus wie für .. Ertrag ist ein Ausdruck. Sie können nicht zwei Erträge haben, da das nicht wirklich Teil des Ausdrucks ist.

Wenn Sie mehrere Werte erhalten möchten, warum sie nicht als Tupel oder Liste ausgeben?

Zum Beispiel:

for(t <- List(1,2,3); l <- List(-1,-2,-3)) 
    yield (t, l) 
0

Vielleicht Ausbeute ist nicht der beste Weg zu gehen? Vielleicht könnte hier ein einfaches Anhängen eines Arrays verwendet werden.

+0

Es gibt keinen semantischen Unterschied zwischen der Verwendung von yield und der Verwendung einer Liste. Der praktische Unterschied betrifft die Speichernutzung, bei der die Ausbeute für große Mengen effizienter ist. – Christopher

5

Nein, Sie können nicht mehrere Yield-Klauseln verwenden, aber es gibt Workarounds. Zum Beispiel:

for (i <- 0 to 10; 
    r <- List(l(i), t(i))) 
yield r 

Sie können Nest-Comprehensions, natürlich, aber das wäre in einer Liste von Listen von Elementen führen, was ich nicht glaube, ist, was Sie wollen.

+1

Warnung, diese Lösung ist O (n^2) –

+0

Für L & T-Listen, die, ich gebe zu, sein Beispiel. Wenn t & l Arrays oder Funktionen wären, wäre das nicht der Fall, oder? –

+0

Rechts, für Arrays indizierten Zugriff ist O (1), also wäre die Lösung O (n). –

1

Hier ist eine Art unabhängige Lösung für eine unbekannte, unterschiedliche Anzahl von Elementen in einer unbekannten Anzahl von Listen:

def xproduct (xx: List [List[_]]) : List [List[_]] = 
    xx match { 
    case aa :: bb :: Nil => 
     aa.map (a => bb.map (b => List (a, b))).flatten  
    case aa :: bb :: cc => 
     xproduct (bb :: cc).map (li => aa.map (a => a :: li)).flatten 
    case _ => xx 
} 

für 2 Listen es ist überentwickelt. Sie könnten es aber anrufen

xproduct (List (l, t)) 
2

Erträge können geschachtelt werden, was dazu führen würde ...

for (i <- 0 to 3) yield { 
    for (j <- 0 to 2) yield (i,j) 
} 

in einem Vektor von Vector:

scala.collection.immutable.IndexedSeq[scala.collection.immutable.IndexedSeq[(Int, Int)]] 
= Vector(Vector((0,0), (0,1), (0,2)), Vector((1,0), (1,1), (1,2)), Vector((2,0), (2,1), (2,2)), Vector((3,0), (3,1), (3,2))) 

for (i <- 0 to 3; 
    j <- 0 to 2) yield (i,j) 

Die abgeflachte Lösung ist semantisch anders.

Verwandte Themen