Search Array of Dictionaries for Value in Swift Search Array of Dictionaries for Value in Swift xcode xcode

Search Array of Dictionaries for Value in Swift


Inside the loop, you need to fetch the "favorite drink" entry from the dictionary, and append it to the array:

for character in characters {    if let drink = character["favorite drink"] {        favoriteDrinkArray.append(drink)    }}

Note, the if let drink = guards against the possibility there is no such entry in the array – if there isn't, you get a nil back, and the if is checking for that, only adding the entry if it's not nil.

You might sometimes see people skip the if let part and instead just write let drink = character["favorite drink"]!, with an exclamation mark on the end. Do not do this. This is known as "force unwrapping" an optional, and if there is ever not a valid value returned from the dictionary, your program will crash.

The behavior with the first example is, if there is no drink you don't add it to the array. But this might not be what you want since you may be expecting a 1-to-1 correspondence between entries in the character array and entries in the drinks array.

If that's the case, and you perhaps want an empty string, you could do this instead:

func favoriteDrinksArrayForCharacters(characters: [[String:String]]) -> [String] {    return characters.map { character in        character["favorite drink"] ?? ""    }}

The .map means: run through every entry in characters, and put the result of running this expression in a new array (which you then return).

The ?? means: if you get back a nil from the left-hand side, replace it with the value on the right-hand side.


let drinks = characters.map({$0["favorite drink"]}) // [Optional("prune juice"), Optional("tea, Earl Grey, hot")]

or

let drinks = characters.filter({$0["favorite drink"] != nil}).map({$0["favorite drink"]!}) // [prune juice, tea, Earl Grey, hot]


Airspeed Velocity's answer is very comprehensive and provides a solution that works. A more compact way of achieving the same result is using the filter and map methods of swift arrays:

func favoriteDrinksArrayForCharacters(characters:Array<Dictionary<String, String>>) -> Array<String> {    // create an array of Strings to dump in favorite drink strings    return characters.filter { $0["favorite drink"] != nil }.map { $0["favorite drink"]! }}

The filter takes a closure returning a boolean, which states whether an element must be included or not - in our case, it checks for the existence of an element for key "favorite drink". This method returns the array of dictionaries satisfying that condition.

The second step uses the map method to transform each dictionary into the value corresponding to the "favorite drink" key - taking into account that a dictionary lookup always returns an optional (to account for missing key), and that the filter has already excluded all dictionaries not having a value for that key, it's safe to apply the forced unwrapping operator ! to return a non optional string.

The combined result is an array of strings - copied from my playground:

["prune juice", "tea, Earl Grey, hot"]