Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I'm trying to figure out the best way in Swift to add values to an Array that is a Value in a Dictionary. I want to build a dictionary of contacts sorted by the first letter of their first name. For example [A : [Aaron, Adam, etc...], B : [Brian, Brittany, ect...], ...]

I found this function:

updateValue(_:forKey:)

And tried using it in a loop:

for contact in self.contacts.sorted() {
    self.contactDictionary.updateValue([contact], forKey: String(describing: contact.characters.first))           
}

But when I tried to use that it replaced the existing array with a new one. I know I can manually check to see if the key in the dictionary exists, if it does, retrieve the array and then append a new value, otherwise add the new key/value pair but I'm not sure if Swift provides an easier/better way to do this.

Any insight would be much appreciated!

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
947 views
Welcome To Ask or Share your Answers For Others

1 Answer

You can use reduce(into:) method (Swift4) and as follow:

let contacts = ["Aaron", "Adam", "Brian", "Brittany", ""]
let dictionary = contacts.reduce(into: [String:[String]]()) { result, element in
    // make sure there is at least one letter in your string else return
    guard let first = element.first else { return }
    // create a string with that initial
    let initial = String(first)
    // initialize an array with one element or add another element to the existing value
    result[initial] = (result[initial] ?? []) + [element]
}
print(dictionary)   // ["B": ["Brian", "Brittany"], "A": ["Aaron", "Adam"]]

If you are using Swift3 or earlier you would need to create a mutable result dictionary inside the closure:

let contacts = ["Aaron", "Adam", "Brian", "Brittany", ""]
let dictionary = contacts.reduce([String:[String]]()) { result, element in
    var result = result
    guard let first = element.first else { return result }
    let initial = String(first)
    result[initial] = (result[initial] ?? []) + [element]
    return result 
}
print(dictionary)   // ["B": ["Brian", "Brittany"], "A": ["Aaron", "Adam"]]

Note that the result is not sorted. A dictionary is an unordered collection. If you need to sort your dictionary and return an array of (key, Value) tuples you can use sorted by key as follow:

let sorted = dictionary.sorted {$0.key < $1.key}
print(sorted)

"[(key: "A", value: ["Aaron", "Adam"]), (key: "B", value: ["Brian", "Brittany"])] "


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...