Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SwiftUI ForEach of dictionary identified issue

Tags:

swiftui

Using the given code below I try to iterate over the dictionary wordList which fails with the issue Instance method 'identified(by:)' requires that '(key: Int, value: [String : String])' conform to 'Hashable'.

So my guess is that I have either to apply the protocol Hashable somehow to the Int of the dictionary or there may be another solution which concerns the usage of .identified(by:)

Thank you very much for the help!

struct ContentView: View {
    @State var wordOrder = ["DE", "EN"]

    let wordList: [Int: [String: String]] = [
        0: [
            "DE": "Hallo Welt",
            "EN": "hello world"
        ],
        1: [
            "DE": "Tschüss",
            "EN": "goodbye"
        ],
        2: [
            "DE": "vielleicht",
            "EN": "maybe"
        ]
    ]

    var body: some View {
        Group {
            NavigationView {
                List() {
                    ForEach(wordList.identified(by: \.self)) { wordListEntry in
                        let lang1 = wordListEntry[wordOrder[0]]
                        let lang2 = wordListEntry[wordOrder[1]]
                        WordRow(lang1, lang2)
                    }
                }
                .navigationBarTitle(Text("Alle Wörter"))
            }
        }
    }
}
like image 207
Daniel Messner Avatar asked Dec 17 '22 16:12

Daniel Messner


1 Answers

It looks like you have a misunderstanding. Based on the code you posted, I guess you think that iterating over a dictionary iterates over the values in the dictionary. But that is not how dictionary iteration works.

When you iterate over a dictionary, you receive pairs. Each pair contains one key and the corresponding value from the dictionary. In your code, wordListEntry's type is (key: Int, value: [String: String]), a pair whose first element is key of type Int and whose second element is value of type [String: String].

I think you want to just iterate over the dictionary's keys, and then look up the corresponding values inside the ForEach body, like this:

ForEach(wordList.keys.sorted().identified(by: \.self)) { key in
    let lang1 = wordListEntry[wordOrder[0]]
    let lang2 = wordListEntry[wordOrder[1]]
    return WordRow(lang1, lang2)
}
like image 159
rob mayoff Avatar answered Feb 08 '23 00:02

rob mayoff