ChatGPT解决这个技术问题 Extra ChatGPT

Iterating Through a Dictionary in Swift

I am a little confused on the answer that Xcode is giving me to this experiment in the Swift Programming Language Guide:

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

I understand that as the dictionary is being transversed, the largest number is being set to the variable, largest. However, I am confused as to why Xcode is saying that largest is being set 5 times, or 1 time, or 3 times, depending on each test.

When looking through the code, I see that it should be set 6 times in "Prime" alone (2, 3, 5, 7, 11, 13). Then it should skip over any numbers in "Fibonacci" since those are all less than the largest, which is currently set to 13 from "Prime". Then, it should be set to 16, and finally 25 in "Square", yielding a total of 8 times.

Am I missing something entirely obvious?


r
rmtheis

Dictionaries in Swift (and other languages) are not ordered. When you iterate through the dictionary, there's no guarantee that the order will match the initialization order. In this example, Swift processes the "Square" key before the others. You can see this by adding a print statement to the loop. 25 is the 5th element of Square so largest would be set 5 times for the 5 elements in Square and then would stay at 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

This prints:

kind: Square kind: Prime kind: Fibonacci


Thank you so much! I was stumped for a little while. I kept adding and removing numbers for each key in hopes of dissecting it, but I wasn't getting anywhere. Your explanation is clear very much appreciated!
dict.forEach { key, value in }
M
Maninderjit Singh
let dict : [String : Any] = ["FirstName" : "Maninder" , "LastName" : "Singh" , "Address" : "Chandigarh"]
dict.forEach { print($0) }

Result would be

("FirstName", "Maninder") ("LastName", "Singh") ("Address", "Chandigarh")


Could you tell me if this example is more efficient in a 1,000 data loop ? Cause i have a JSON that big, so it take me a 1GB processing at the end. Newer devices wont crash, but in my iphone 5s 16GB crash on half of that.
This seems a bit misleading given the original question is about whether dictionaries maintain their order then you post an example where they maintain their order when they don't.
l
l --marc l

This is a user-defined function to iterate through a dictionary:

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

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

j
jabbyApps

Here is an alternative for that experiment (Swift 3.0). This tells you exactly which kind of number was the largest.

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

n
norbDEV

If you want to iterate over all the values:

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

I hate the fact so much, that this is correct. In stupid Joda speak to the creator of swift everyone must speak! 🤮
a
aturan23

You can also use values.makeIterator() to iterate over dict values, like this:

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

You can also do the iteration like this, in a more swifty style:

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

sbItems is dict of type [String : NSManagedObject]