简体   繁体   中英

Swift - How to get index of Dictionary element from value?

I am using a Array of Dictionary (Swift 4.1) to store the value of language name and language code:

var voiceLanguagesList: [Dictionary<String, String>] = []

I am appending array of dictionary by this method:

for voice in AVSpeechSynthesisVoice.speechVoices() {
            let voiceLanguageCode = (voice as AVSpeechSynthesisVoice).language

            if let languageName = Locale.current.localizedString(forLanguageCode: voiceLanguageCode) {
                let dictionary = [ControllerConstants.ChooseLanguage.languageName: languageName, ControllerConstants.ChooseLanguage.languageCode: voiceLanguageCode]

                voiceLanguagesList.append(dictionary)
            }
        }

Now let say I have stored value of the element in userDefaults:

let languageName = UserDefaults.standard.object(forKey: ControllerConstants.UserDefaultsKeys.languageName) as? String
        let languageCode = UserDefaults.standard.object(forKey: ControllerConstants.UserDefaultsKeys.languageCode) as? String

I want to get the index of the dictionary where the value is languageName and languageCode . I gone through other answers but didn't find any good solution.

SourceCode: https://github.com/imjog/susi_iOS/tree/voice

File Link: https://github.com/imjog/susi_iOS/blob/voice/Susi/Controllers/LanguagePickerController/LanguagePickerController.swift

Dictionaries are unordered. They do not have an index. Dictionaries have keys, which are some hashable value.

All the keys in a dictionary are unique, but not all the values are.

You can have a Dictionary of type [String:Int] with the values

["a": 1, "b": 1, "c": 1]

What is the key for value 1 in that case? Would any key that contains that value be ok? In that case you could loop through the key/value pairs until you find a matching value and return that key, but there's no such thing as the first matching value because, as mentioned, dictionaries are unordered.

I don't see the need of using dictionary here. You can simply create a new type Language and do the search as below.

struct Language: Equatable {
    var code: String
    var name: String
}

var languages = [Language]()
languages.append(Language(code: "1", name: "English"))
languages.append(Language(code: "2", name: "Hindi"))

let languageToSearch = Language(code: "2", name: "Hindi")

print(languages.index(of: languageToSearch) ?? "Not found")

As have been already said by others, I dont see the point of using an array of dictionaries as a model for your table view... however, if I understood your question, could this help? Greetings

var testDictArray: [Dictionary<String, String>] = [] // Just a test, an array of dictionaries

// Filling the dictionary with example data
testDictArray.append(
    ["A0":"a0",
    "B0":"b0",
    "C0":"c0"]
)
testDictArray.append(
    ["A1":"a1",
     "B1":"b1",
     "C1":"c1",
     "D1":"d1"]
)
testDictArray.append(
    ["A2":"a2",
     "B2":"b2"]
)

// The example values you want to find
let upperCase = "B2"
let lowerCase = "b2"

// Some loops...
var foundedIndex: Int? = nil
for index in 0..<testDictArray.count {
    for (key, value) in testDictArray[index] {
        if (key, value) == (upperCase, lowerCase) {
            foundedIndex = index
            break
        }
    }
    if foundedIndex != nil {
        break
    }
}

// Printing result
if let myIndex = foundedIndex {
    print("The index is \(myIndex)") // The example returns 2
} else {
    print("No index found :(")
}

Dictionary is key-value paired

If you want to get index of Dictionary element from value.
You can try with array of tuple like below:

let dict = [("key0", "value0"), ("key1", "value1")]
let index = dict.index { $1 == "value1" } ?? 0
print(index)    // 1

Hope it is useful!

I have an array of dictionaries where dictionary is of type <String,Any> .

After some research and hit and trial, I have found something which works for me.

if let index = yourArray?.firstIndex(
                where: {
                  ($0 as AnyObject)["Title"] as? String == NSLocalizedString("New Location", comment: "")
            }
                )
            {
                print(index)
                //your operations here

            }

PS - ($0 as AnyObject)["Title"] as? String is the text you wish to find..

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM