Is there a way to iterate through a Dictionary
in a ForEach
loop? Xcode says
Generic struct 'ForEach' requires that '[String : Int]' conform to 'RandomAccessCollection'
so is there a way to make Swift Dictionaries conform to RandomAccessCollection
, or is that not possible because Dictionaries are unordered?
One thing I've tried is iterating the dictionary's keys:
let dict: [String: Int] = ["test1": 1, "test2": 2, "test3": 3] ... ForEach(dict.keys) {...}
But keys
is not an array of String
s, it's type is Dictionary<String, Int>.Keys
(not sure when that was changed). I know I could write a helper function that takes in a dictionary and returns an array of the keys, and then I could iterate that array, but is there not a built-in way to do it, or a way that's more elegant? Could I extend Dictionary
and make it conform to RandomAccessCollection
or something?
With this, it's possible to iterate through a dictionary in a KeyValuePair agnostic way: var dictionary = new Dictionary<int, string>(); // ... foreach (var (key, value) in dictionary) { // ... } Save this answer.
ForEach in SwiftUI is a view struct in its own right, which means you can return it directly from your view body if you want. You provide it an array of items, and you may also need to tell SwiftUI how it can identify each of your items uniquely so it knows how to update them when values change.
There is no order. Dictionaries in Swift are an unordered collection type. The order in which the values will be returned cannot be determined. If you need an ordered collection of values, I recommend using an array.
Swift dictionary is an unordered collection of items. It stores elements in key/value pairs. Here, keys are unique identifiers that are associated with each value.
You can sort your dictionary to get (key, value) tuple array and then use it.
struct ContentView: View { let dict = ["key1": "value1", "key2": "value2"] var body: some View { List { ForEach(dict.sorted(by: >), id: \.key) { key, value in Section(header: Text(key)) { Text(value) } } } } }
Simple answer: no.
As you correctly pointed out, a dictionary is unordered. The ForEach watches its collection for changes. These changes includes inserts, deletions, moves and update. If any of those changes occurs, an update will be triggered. Reference: https://developer.apple.com/videos/play/wwdc2019/204/ at 46:10:
A ForEach automatically watches for changes in his collection
I recommend you watch the talk :)
You can not use a ForEach because:
UITableView
reuses cells when cells can be recycled, a List
is backed by UITableViewCells
, and I think a ForEach
is doing the same thing), it needs to compute what cell to show. It does that by querying an index path from the data source. Logically speaking, an index path is useless if the data source is unordered.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With