Lặp lại từ điển trong Swift


221

Tôi hơi bối rối về câu trả lời rằng Xcode đang đưa tôi đến thử nghiệm này trong Hướng dẫn ngôn ngữ lập trình 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

Tôi hiểu rằng khi từ điển đang được chuyển đổi, số lượng lớn nhất đang được đặt thành biến , largest. Tuy nhiên, tôi bối rối không hiểu tại sao Xcode lại nói rằng largestđang được đặt 5 lần, hoặc 1 lần, hoặc 3 lần, tùy thuộc vào mỗi thử nghiệm.

Khi xem qua mã, tôi thấy rằng nó nên được đặt 6 lần trong "Prime" một mình (2, 3, 5, 7, 11, 13). Sau đó, nó nên bỏ qua bất kỳ số nào trong "Fibonacci" vì những số này đều nhỏ hơn số lớn nhất, hiện được đặt thành 13 từ "Prime". Sau đó, nó nên được đặt thành 16, và cuối cùng là 25 trong "Square", mang lại tổng cộng 8 lần.

Tôi có thiếu một cái gì đó hoàn toàn rõ ràng?

Câu trả lời:


355

Từ điển trong Swift (và các ngôn ngữ khác) không được đặt hàng. Khi bạn lặp lại từ điển, không có gì đảm bảo rằng thứ tự sẽ khớp với thứ tự khởi tạo. Trong ví dụ này, Swift xử lý phím "Square" trước các phím khác. Bạn có thể thấy điều này bằng cách thêm một câu lệnh in vào vòng lặp. 25 là phần tử thứ 5 của Square nên lớn nhất sẽ được đặt 5 lần cho 5 phần tử trong Square và sau đó sẽ ở mức 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

Bản in này:

kind: Square
kind: Prime
kind: Fibonacci

1
Cảm ơn bạn rất nhiều! Tôi đã bối rối một chút. Tôi tiếp tục thêm và xóa số cho mỗi khóa với hy vọng mổ xẻ nó, nhưng tôi không đi đến đâu cả. Giải thích của bạn rõ ràng rất nhiều đánh giá cao!
Nick Kohrn

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

Kết quả sẽ là

("FirstName", "Maninder") ("LastName", "Singh") ("Địa chỉ", "Chandigarh")


Bạn có thể cho tôi biết nếu ví dụ này hiệu quả hơn trong vòng lặp dữ liệu 1.000? Vì tôi có một JSON lớn, nên cuối cùng tôi phải xử lý 1GB. Các thiết bị mới hơn sẽ không gặp sự cố, nhưng trong iphone 5s 16GB của tôi bị sập một nửa số đó.
Daniel Arantes Loverde

Điều này có vẻ hơi sai lệch khi đưa ra câu hỏi ban đầu là về việc từ điển có duy trì trật tự của họ hay không, sau đó bạn đăng một ví dụ nơi họ duy trì trật tự khi họ không làm.
Declan McKenna

12

Đây là một hàm do người dùng định nghĩa để lặp qua từ điển:

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

Đây là một thay thế cho thí nghiệm đó (Swift 3.0). Điều này cho bạn biết chính xác loại số nào là lớn nhất.

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

Nếu bạn muốn lặp lại tất cả các giá trị:

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

Tôi ghét thực tế rất nhiều, rằng điều này là chính xác. Trong Joda ngu ngốc nói chuyện với người tạo ra swift mọi người phải nói! 🤮
Sebastian


1

Bạn cũng có thể sử dụng values.makeIterator()để lặp lại các giá trị dict, như thế này:

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

Bạn cũng có thể thực hiện phép lặp như thế này, theo phong cách dễ hiểu hơn:

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

* sbItemslà loại chính tả[String : NSManagedObject]

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.