2012-04-14 3 views
7

Ich versuche, jedes Paar von Werten in meinem Array mit for und Ausbeute zu tauschen, und bisher bin ich sehr erfolglos. Was ich habe, ist versucht, wie folgt:Austauschen von Array-Werten mit for und yield scala

val a = Array(1,2,3,4,5) //What I want is Array(2,1,4,3,5) 

for(i<-0 until (a.length-1,2),r<- Array(i+1,i)) yield r 

Die oben angegebenen Schnipsel des Vektors 2,1,4,3 zurückgibt (und der 5 weggelassen)

jemand kann darauf hinweisen, was ich falsch hier tue und wie bekommt man die richtige Umkehrung für und Erträge?

Dank

+7

Dies ist von "Scala für die ungeduldig". Übung 3.2 – Zotov

Antwort

11

Es wäre einfacher, wenn Sie for/yield verwenden didin't:

a.grouped(2) 
    .flatMap{ 
    case Array(x,y) => Array(y,x) 
    case Array(x) => Array(x) 
    }.toArray // Array(2, 1, 4, 3, 5) 
+2

Dies ist wahrscheinlich eine reife Art, Dinge zu tun. Ich lerne Scala und habe mich gefragt, ob das Gleiche mit/Ausbeute erreicht werden könnte. –

+0

@sc_ray, Die 'for/yield'-Konstruktion macht die Dinge viel schöner, aber das passt nicht gut dazu. – dhg

35
a.grouped(2).flatMap(_.reverse).toArray 

oder wenn Sie für/Ertrag (viel weniger prägnant in diesem Fall und in der Tat erweitert auf den gleichen Code):

(for {b <- a.grouped(2); c <- b.reverse} yield c).toArray 
+0

Ich mag die Verwendung von 'reverse'. Nett. – dhg

+0

Die Übung sagt, machen Sie eine Schleife, dann machen Sie eine for/yield, keine funktionale Lösung. Schön aber ... – Rob

8

weiß ich nicht, ob die OP Scal liest a für den Ungeduldigen, aber das war Übung 3.3.

Ich mag die Kartenlösung, aber wir sind noch nicht an diesem Kapitel, also ist das meine hässliche Implementierung, die die benötigte/Ausbeute verwendet. Sie können wahrscheinlich eine Ertragslogik in eine Wache/Definition verschieben.

for(i <- 0 until(a.length,2); j <- (i+1).to(i,-1) if(j<a.length)) yield a(j) 

Ich bin ein Java-Typ, also habe ich keine Bestätigung für diese Behauptung, aber ich bin neugierig, was der Overhead der Karten/Gruppierung und Iteratoren sind. Ich vermute, dass alles auf denselben Java-Byte-Code kompiliert wird.

+0

Schön. Dies scheint mehr im Geist der Übung zu liegen. –

+0

Gute Antwort auf die gestellte Frage. –

0

Eine weitere einfache, für Yield-Lösung:

def swapAdjacent(array: ArrayBuffer[Int]) = { 
    for (i <- 0 until array.length) yield (
     if (i % 2 == 0) 
      if (i == array.length - 1) array(i) else array(i + 1) 
     else array(i - 1) 
    ) 
} 
0

Wenn Sie Übungen 3.2 und 3.3 in Scala tun hier für Ungeduldige sind beide meine Antworten. Sie sind die gleichen mit der Logik bewegt sich herum.

/** Excercise 3.2 */ 
for (i <- 0 until a.length if i % 2 == 1) {val t = a(i); a(i) = a(i-1); a(i-1) = t } 
/** Excercise 3.3 */ 
for (i <- 0 until a.length) yield { if (i % 2 == 1) a(i-1) else if (i+1 <= a.length-1) a(i+1) else a(i) } 
0

Ich habe meine Lösung, aber ohne Ertrag. Vielleicht wird jemand es nützlich finden.

def swap(x: Array[Int]): Array[Int] = { 
    for (i <- 0 until x.length-1 by 2){ 
     var left = x(i) 
     x(i) = x(i+1) 
     x(i+1) = left 
    } 
    x 
    }