somu
(somu)
1
Hi,
I would like to group a list of alphabets and get a dictionary containing the number of times of each alphabet has occurred.
I could loop through and build the dictionary, just wondering if there was a better way.
let list = ["a", "b", "c", "d", "a", "c"]
Expected Output:
["d": 1, "c": 2, "b": 1, "a": 2]
Attempt so far:
let grouped = Dictionary(grouping: list, by: { $0 }) //This gives the array not the count
somu
(somu)
2
Just managed to find on the swift blog:
let grouped = Dictionary(grouping: list, by: { $0 }).mapValues { items in items.count }
Question:
Just wondering would it be 2 iterations ? Is there a better way ?
Thanks to the Dictionary Blog:
So sorry I should have read the swift blog on Dictionary more thoroughly, clearly explains the above situation.
Reference: Transforming a Dictionary’s Values
tkrajacic
(Thomas Krajacic)
3
Further down in the chapter you linked you will find what you are looking for:
let list = ["a", "b", "c", "d", "a", "c"]
var grouped: [String: Int] = [:]
for item in list {
grouped[item, default: 0] += 1
}
You can also do it in a more functional way:
let list = ["a", "b", "c", "d", "a", "c"]
let grouped = list.reduce(into: [:]) { result, character in
result[character, default: 0] += 1
}
4 Likes
somu
(somu)
4
This is awesome, thank you so much !!!!
Lantua
5
Just wanna throw-in, I tend to use this
let list = ["a", "b", "c", "d", "a", "c"]
let ones = repeatElement(1, count: list.count)
let counted = Dictionary(zip(list, ones), uniquingKeysWith: +)
// ["c": 2, "b": 1, "a": 2, "d": 1]
6 Likes
jazzbox
(Bernd Ohr)
7
Hey cool!
And for sequences there is no need to count the list:
extension Dictionary where Value == Int {
init<S: Sequence>(counted list: S) where S.Element == Key {
let ones = repeatElement(1, count: Int.max)
try! self.init(zip(list, ones), uniquingKeysWith: +)
}
}
let list = ["a", "b", "c", "d", "a", "c"]
let counted = Dictionary(counted: list)
2 Likes
somu
(somu)
8
Thank you so much guys, really nice solutions.