ale*_*wis 3 arrays histogram ios swift
我正在尝试编写一个在a上运行的通用直方图函数Array,但由于Type'Element'不符合协议'Hashable',我遇到了困难.
extension Array {
func histogram() -> [Array.Element: Int] {
return self.reduce([Array.Element: Int]()) { (acc, key) in
let value = (acc[key] == nil) ? 1 : (acc[key]! + 1)
return acc.dictionaryByUpdatingKey(key: key, value: value)
}
}
}
Run Code Online (Sandbox Code Playgroud)
其中dictionaryByUpdatingKey(...)变异现有词典如下:
extension Dictionary {
func dictionaryByUpdatingKey(key: Dictionary.Key, value: Dictionary.Value) -> Dictionary {
var mutableSelf = self
let _ = mutableSelf.updateValue(value, forKey: key)
return mutableSelf
}
}
Run Code Online (Sandbox Code Playgroud)
我曾尝试更换Array.Element用AnyHashable,然后强迫key as! AnyHashable,但这似乎凌乱和返回类型最好是相同类型的Array.Element,而不是AnyHashable.
我希望使用Array扩展名如下:
let names = ["Alex", "Alex", "James"]
print(names.histogram()) // ["James": 1, "Alex": 2]
Run Code Online (Sandbox Code Playgroud)
要么
let numbers = [2.0, 2.0, 3.0]
print(numbers.histogram()) // [3.0: 1, 2.0: 2]
Run Code Online (Sandbox Code Playgroud)
将通用where子句:添加where Element: Hashable到您的扩展中:
extension Array where Element: Hashable {
func histogram() -> [Array.Element: Int] {
return self.reduce([Array.Element: Int]()) { (acc, key) in
let value = acc[key, default: 0] + 1
return acc.dictionaryByUpdatingKey(key: key, value: value)
}
}
}
Run Code Online (Sandbox Code Playgroud)
我还整合了@ MartinR建议使用新default值进行字典查找.
使用reduce(into:_:)您可以更简单有效地完成这项工作:
extension Array where Element: Hashable {
func histogram() -> [Element: Int] {
return self.reduce(into: [:]) { counts, elem in counts[elem, default: 0] += 1 }
}
}
Run Code Online (Sandbox Code Playgroud)