Durch ein Wörterbuch in Swift iterieren

221

Ich bin ein wenig verwirrt über die Antwort, die Xcode mir auf dieses Experiment im Swift Programming Language Guide gibt:

// Use a for-in to iterate through a dictionary (experiment)

let interestingNumbers = [
    "Prime": [2, 3, 5, 7, 11, 13],
    "Fibonacci": [1, 1, 2, 3, 5, 8],
    "Square": [1, 4, 9, 16, 25]
]
var largest = 0
for (kind, numbers) in interestingNumbers {
    for number in numbers {
        if number > largest {
            largest = number
        }
    }
}
largest

Ich verstehe, dass beim Durchlaufen des Wörterbuchs die größte Zahl auf die Variable gesetzt wird largest. Ich bin jedoch verwirrt darüber, warum Xcode sagt, dass dies largestje nach Test fünfmal oder einmal oder dreimal eingestellt wird.

Wenn ich den Code durchschaue, sehe ich, dass er allein in "Prime" 6 Mal eingestellt werden sollte (2, 3, 5, 7, 11, 13). Dann sollte es alle Zahlen in "Fibonacci" überspringen, da diese alle kleiner als die größten sind, die derzeit von "Prime" auf 13 gesetzt ist. Dann sollte es auf 16 und schließlich 25 in "Quadrat" gesetzt werden, was insgesamt 8 Mal ergibt.

Vermisse ich etwas ganz Offensichtliches?

Nick Kohrn
quelle

Antworten:

355

Wörterbücher in Swift (und anderen Sprachen) werden nicht bestellt. Wenn Sie das Wörterbuch durchlaufen, gibt es keine Garantie dafür, dass die Reihenfolge mit der Initialisierungsreihenfolge übereinstimmt. In diesem Beispiel verarbeitet Swift den "Quadrat" -Schlüssel vor den anderen. Sie können dies sehen, indem Sie der Schleife eine print-Anweisung hinzufügen. 25 ist das 5. Element des Quadrats, so dass das größte Element für die 5 Elemente des Quadrats fünfmal festgelegt wird und dann bei 25 bleibt.

let interestingNumbers = [
    "Prime": [2, 3, 5, 7, 11, 13],
    "Fibonacci": [1, 1, 2, 3, 5, 8],
    "Square": [1, 4, 9, 16, 25]
]
var largest = 0
for (kind, numbers) in interestingNumbers {
    println("kind: \(kind)")
    for number in numbers {
        if number > largest {
            largest = number
        }
    }
}
largest

Dies druckt:

kind: Square
kind: Prime
kind: Fibonacci
Strich
quelle
1
Ich danke dir sehr! Ich war für eine Weile ratlos. Ich fügte immer wieder Zahlen für jeden Schlüssel hinzu und entfernte ihn in der Hoffnung, ihn zu zerlegen, aber ich kam nicht weiter. Ihre Erklärung ist klar sehr geschätzt!
Nick Kohrn
15
let dict : [String : Any] = ["FirstName" : "Maninder" , "LastName" : "Singh" , "Address" : "Chandigarh"]
dict.forEach { print($0) }

Ergebnis wäre

("Vorname", "Maninder") ("Nachname", "Singh") ("Adresse", "Chandigarh")

Maninderjit Singh
quelle
Können Sie mir sagen, ob dieses Beispiel in einer 1.000-Datenschleife effizienter ist? Weil ich einen so großen JSON habe, brauche ich am Ende eine 1-GB-Verarbeitung. Neuere Geräte stürzen nicht ab, aber in meinem iPhone 5s stürzen 16 GB auf die Hälfte davon ab.
Daniel Arantes Loverde
Dies scheint etwas irreführend zu sein, da die ursprüngliche Frage lautet, ob Wörterbücher ihre Reihenfolge beibehalten. Dann veröffentlichen Sie ein Beispiel, in dem sie ihre Reihenfolge beibehalten, wenn sie dies nicht tun.
Declan McKenna
12

Dies ist eine benutzerdefinierte Funktion zum Durchlaufen eines Wörterbuchs:

func findDic(dict: [String: String]){
    for (key, value) in dict{
    print("\(key) : \(value)")
  }
}

findDic(dict: ["Animal":"Lion", "Bird":"Sparrow"])
//prints Animal : Lion 
         Bird : Sparrow
Rawand Saeed
quelle
11

Hier ist eine Alternative für dieses Experiment (Swift 3.0). Hier erfahren Sie genau, welche Art von Nummer die größte war.

let interestingNumbers = [
"Prime": [2, 3, 5, 7, 11, 13],
"Fibonacci": [1, 1, 2, 3, 5, 8],
"Square": [1, 4, 9, 16, 25],
]

var largest = 0
var whichKind: String? = nil

for (kind, numbers) in interestingNumbers {
    for number in numbers {
    if number > largest {
        whichKind = kind
        largest = number
    }
  }
}

print(whichKind)
print(largest)

OUTPUT:
Optional("Square")
25
jabbyApps
quelle
8

Wenn Sie alle Werte durchlaufen möchten:

dict.values.forEach { value in
    // print(value)
}
norbDEV
quelle
Ich hasse die Tatsache so sehr, dass dies richtig ist. Im dummen Joda sprich mit dem Schöpfer von Swift, jeder muss sprechen! 🤮
Sebastian
4

Arrays sind geordnete Sammlungen, Wörterbücher und Mengen sind jedoch ungeordnete Sammlungen. Daher können Sie die Reihenfolge der Iteration in einem Wörterbuch oder einer Menge nicht vorhersagen.

Lesen Sie diesen Artikel, um mehr über Sammlungstypen zu erfahren : Swift Programming Language

Rachit Rawat
quelle
1

Sie können auch values.makeIterator()diktierte Werte wie folgt durchlaufen:

for sb in sbItems.values.makeIterator(){
    // do something with your sb item..
    print(sb)
}

Sie können die Iteration auch wie folgt in einem schnelleren Stil ausführen:

sbItems.values.makeIterator().forEach{
    // $0 is your dict value..
    print($0) 
}

* sbItemsist ein Diktat des Typs[String : NSManagedObject]

Yonathan Goriachnick
quelle