No. But it is pretty hard to read this, even though the result is very easy to understand : counting the frequency in a sequence.
For readibility, it could be written in more extended form:
extension Sequence where Element: Hashable { //extension on sequence where element conforms to hashable protocol
var frequencies: [Element: Int] { //dictionary of key element and value int
return Dictionary(self.map{ ($0, 1)}, uniquingKeysWith: { $0 + $1}) //creates new dictionary for key-value pairs in sequence and increments the value for duplicate keys
}
}
for example,
let res = ["a", "b", "c", "b", "d", "a", "a"].frequencies
yelds
["b": 2, "a": 3, "d": 1, "c": 1]
So, what it does,
map creates a dictionary from the sequence with pairs of the element of the sequence and 1
let res2 = ["a", "b", "c", "b", "d", "a", "a"].map{ ($0, 1)}
[("a", 1), ("b", 1), ("c", 1), ("b", 1), ("d", 1), ("a", 1), ("a", 1)]
From this, it creates the dictionary
("a", 1), ("b", 1), ("c", 1) starting with ["a": 1, "b": 1, "c":1]
When it meets an item with a duplicate key, such as ("b", 1), instead of trying to add a new item in dictionary (which would fail because key "b" already exists), iit modifies the value for the existing key ("b") by executing the closure which increments the value (of 1) by 1
then again, second ("a", 1) is not appended to the dictionary but the value for key "a" is modified from "a": 1 to "a":2.
This gives Dictionary(res2, uniquingKeysWith: +)
["b": 2, "a": 3, "d": 1, "c": 1]
Note : this is explained in documentation:
init<S>(_ keysAndValues: S, uniquingKeysWith combine: (Dictionary.Value, Dictionary.Value) throws -> Dictionary.Value) rethrows where S : Sequence, S.Element == (Key, Value)
init<S>(_ keysAndValues: S, uniquingKeysWith combine: (Dictionary.Value, Dictionary.Value) throws -> Dictionary.Value) rethrows where S : Sequence, S.Element == (Key, Value)
Creates a new dictionary from the key-value pairs in the given sequence, using a combining closure to determine the value for any duplicate keys.
Note 1: to simply create a dictionary from a sequence, you can use:
Dictionary(uniqueKeysWithValues: S), such as
Dictionary(uniqueKeysWithValues: [("d",1), ("e",2)])
which returns
["d": 1, "e": 2]
but if sequence has a duplicate key
[("d",1), ("e",2), ("d",3) ]
it fails with: Fatal error: Duplicate values for key: 'd' ; that's the interest of Dictionary(res2, uniquingKeysWith:) instead of crashing, it will update the value for the duplicating key according to the passed closure.
Note 2: you can play with the closure, for instance adding ten times the value ($1)
extension Sequence where Element: Hashable { //extension on sequence where element conforms to hashable protocol
var frequencies: [Element: Int] { //dictionary of key element and value int
return Dictionary(self.map{ ($0, 1)}, uniquingKeysWith: { $0 + 10*$1})
}
}
returns:
["b": 11, "a": 21, "d": 1, "c": 1]
or multiply the current count ($0) by 10 each time a new occurrence is found
extension Sequence where Element: Hashable { //extension on sequence where element conforms to hashable protocol
var frequencies: [Element: Int] { //dictionary of key element and value int
return Dictionary(self.map{ ($0, 1)}, uniquingKeysWith: { 10*$0 + $1}) //creates new dictionary for key-value pairs in sequence and increments the value for duplicate keys
}
}
returns:
["b": 11, "a": 111, "d": 1, "c": 1]
Edited (for fun), if you want to give stars
You could also write :
extension Sequence where Element: Hashable { //extension on sequence where element conforms to hashable protocol
var frequencies: [Element: String] { //dictionary of key element and value int
return Dictionary(self.map{ ($0, "✩")}, uniquingKeysWith: { $0 + $1 })
}
}
let res = ["a", "b", "c", "b", "d", "a", "a"].frequencies
print(res)
and get
["b": "✩✩", "a": "✩✩✩", "d": "✩", "c": "✩"]