2016-03-28 6 views
5

Ich möchte in der Lage sein, mein Array von Objekten mit map in Swift der Fliege zu ändern, ohne durch jedes Element zu durchlaufen.Karte ändern Array von Objekten in Swift 2.2 (3.0)

Bevor hier in der Lage waren, so etwas zu tun (Beschrieben in mehr Details here:

gnomes = gnomes.map { (var gnome: Gnome) -> Gnome in 
    gnome.age = 140 
    return gnome 
} 

Vielen Dank für Erica Sadun und andere haben neue Vorschläge durchgegangen und wir jetzt von C-Stil Loswerden Schleifen und var innerhalb der Schleife verwendet wird.

in meinem Fall bin immer ich zum ersten Mal eine Warnung, die var in dann einem Fehler zu entfernen, meine gnome eine konstante ist (natürlich)

Meine Frage ist: Wie ändern wir Arrays innerhalb eines map oder die neu gestalteten Loops für die Angelegenheit vollständig für Swift 3.0 vorbereitet werden?

Antwort

13

Wenn Sie diese Syntax halten möchten, verwenden Sie nur eine (änderbare) temporäre Variable

gnomes = gnomes.map { (gnome: Gnome) -> Gnome in 
    var mutableGnome = gnome 
    mutableGnome.age = 140 
    return mutableGnome 
} 
12

(folgt unterhalb den Fall, in dem Gnome ist ein Referenztyp, eine Klasse - da haben Sie nicht uns gezeigt, wie man Gnome definiert hat für den Fall, dass Gnome als Werttyp (eine Struktur), siehe @. Vadian: s Antwort)


Die Entfernung von var wird Effekt nicht .map Verwendung veränderbare Mitglieder eines Arrays von Referenz Typobjekte zu mutieren. Das heißt, Sie könnten einfach Ihren alten Ansatz verwenden (unterlassen Sie jedoch die var in der .map Verschluss Signatur).

class Gnome { 
    var age = 42 
} 

var gnomes = [Gnome(), Gnome(), Gnome()] 

gnomes = gnomes.map { 
    $0.age = 150 
    return $0 
} 

/* result */ 
gnomes.forEach { print($0.age) } // 3x 150 

jedoch, falls Sie wollen einfach nur eher Ihre ursprüngliche Array ändern als das Ergebnis von .map in ein neues Array zuweisen, .forEach könnte besser geeignet als .map sein.

gnomes.forEach { $0.age = 140 } 

/* result */ 
gnomes.forEach { print($0.age) } // 3x 140 
+0

gibt einen Fehler zurück "$ 0 ist unveränderlich". Es ist meine Schuld.Ich hätte präzisieren sollen :(Ich benutze Strukturen anstelle von Klassen, ich wette, dass sie standardmäßig unwandelbar sind – kernelpanic

+0

@kernelpanic Da du uns deine 'Gnome' Klasse nicht gezeigt hast, musste ich eine eigene hinzufügen Sind Sie sicher, dass die "Alter" -Eigenschaft Ihrer Klasse eine veränderliche ist (sowie Ihr Array von Gnomen)? Das obige funktioniert gut für mich auf Swift 2.2 und Xcode 7.3. – dfri

+0

@dfri Ich vermute, dass "Gnome" ist ein struct – vadian

1

Gegeben:

struct Gnome { 
    var age: Int = 0 
} 

var gnomes = Array(count: 5, repeatedValue: Gnome()) 

... gibt es zwei anständige Optionen. Die erste ist, wie es @vadian zu setzen:

gnomes = gnomes.map{ 
    var gnome = $0 
    gnome.age = 70 
    return gnome 
} 

Während der zweiter hält die Kontrolle über „Alter“ private und vereinfacht die Zuordnung am Punkt des Aufrufs:

struct Gnome { 
    private(set) var age: Int = 0 

    func aged(age: Int) -> Gnome { 
     var gnome = self 
     gnome.age = age 
     // any other ageing related changes 
     return gnome 
    } 
} 

gnomes = gnomes.map{ $0.aged(140) } 

Natürlich Referenztypen haben noch ihre Platz in der Programmierung, die in diesem Fall gut passen könnte. Die Reibung, die wir hier erfahren, deutet darauf hin, dass wir versuchen, diese Strukturen so zu behandeln, als wären sie Objekte. Wenn das das Verhalten ist, das Sie benötigen, sollten Sie die Implementierung von Gnome als class in Erwägung ziehen.