Ітерація через словник у Swift


222

Я трохи розгублений у відповіді, що Xcode дає мені цей експеримент у посібнику з мови програмування Swift:

// 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

Я розумію , що в якості словника в даний час пробігтися, найбільше число в даний час набір змінної, largest. Однак мене бентежить питання про те, чому Xcode каже, largestщо встановлюється 5 разів, або 1 раз, або 3 рази, залежно від кожного тесту.

Переглядаючи код, я бачу, що він повинен бути встановлений 6 разів лише в "Prime" (2, 3, 5, 7, 11, 13). Тоді слід пропустити будь-які цифри у "Фібоначчі", оскільки всі вони менше, ніж найбільший, який наразі на "Prime" встановлений на 13. Тоді його слід встановити на 16, і, нарешті, на 25 у "Квадрат", виходячи загалом у 8 разів.

Я пропускаю щось абсолютно очевидне?

Відповіді:


355

Словники в Swift (та інших мовах) не впорядковуються. Коли ви переглядаєте словник, немає гарантії, що порядок відповідає порядку ініціалізації. У цьому прикладі Свіфт обробляє клавішу "Квадрат" перед іншими. Це можна побачити, додавши в цикл оператор друку. 25 - це 5-й елемент квадрата, тому найбільший розміщуватиметься 5 разів для 5 елементів на площі, а потім залишатиметься на рівні 25.

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

Це відбитки:

kind: Square
kind: Prime
kind: Fibonacci

1
Дуже дякую! Я трохи спотикався. Я продовжував додавати та вилучати цифри для кожної клавіші, сподіваючись розібрати її, але нікуди не дістався. Ваше пояснення, зрозуміло, дуже вдячний!
Нік Корн

15
let dict : [String : Any] = ["FirstName" : "Maninder" , "LastName" : "Singh" , "Address" : "Chandigarh"]
dict.forEach { print($0) }

Результат був би

("FirstName", "Maninder") ("LastName", "Singh") ("Адреса", "Chandigarh")


Чи можете ви сказати мені, чи цей приклад є більш ефективним у циклі даних 1000? Тому що у мене JSON такий великий, тому в кінці часу мені потрібно обробляти 1 Гб. Нові пристрої звикли виходити з ладу, але в моєму iphone 5s 16GB випадає на половину цього.
Даніель Арантес Ловерде

Це здається трохи оманливим, враховуючи оригінальний питання про те, чи підтримують словники свій порядок, то ви розміщуєте приклад, коли вони підтримують свій порядок, коли вони цього не роблять.
Деклан МакКенна

12

Це визначена користувачем функція ітерації через словник:

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

findDic(dict: ["Animal":"Lion", "Bird":"Sparrow"])
//prints Animal : Lion 
         Bird : Sparrow

11

Ось альтернатива цього експерименту (Swift 3.0). Це точно говорить вам про те, яка кількість була найбільшою.

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

8

Якщо ви хочете повторити всі значення:

dict.values.forEach { value in
    // print(value)
}

Я так ненавиджу факт, що це правильно. У дурному Джоді розмовляють із творцем стрімкого, кожен повинен говорити! 🤮
Себастьян

4

Масиви - це упорядковані колекції, але словники та набори - це не упорядковані колекції. Таким чином, ви не можете передбачити порядок ітерації у словнику чи наборі.

Прочитайте цю статтю, щоб дізнатися більше про типи колекцій: швидка мова програмування


1

Ви також можете використовувати values.makeIterator()для повторення значень dict, як це:

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

Ви також можете зробити ітерацію, як це, у більш швидкому стилі:

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

* sbItemsце диктант типу[String : NSManagedObject]

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.