I\'m trying to write a generic histogram function that operates on an Array, but I\'m running into difficulties as Type \'Element\' does not conform to prot
First, you could limit the Element type to only be Hashable.
extension Array where Array.Element:Hashable {
After this, you might get another error because the swift compiler is a little "overstrained". Try to give him a hint:
typealias RT = [Array.Element: Int]
and use it everywhere. So:
extension Array where Array.Element:Hashable {
typealias RT = [Array.Element: Int]
func histogram() -> RT {
return self.reduce(RT()) { (acc, key) in
let value = (acc[key] == nil) ? 1 : (acc[key]! + 1)
return acc.dictionaryByUpdatingKey(key: key, value: value)
}
}
}
finally should work.
Add the generic where clause: where Element: Hashable to your extension:
extension Sequence where Element: Hashable {
func histogram() -> [Element: Int] {
return self.reduce([Element: Int]()) { (acc, key) in
let value = acc[key, default: 0] + 1
return acc.dictionaryByUpdatingKey(key: key, value: value)
}
}
}
I also incorporated @MartinR's suggestion of using the new default value for dictionary look ups.
Using reduce(into:_:) you can do this much more simply and efficiently:
extension Sequence where Element: Hashable {
func histogram() -> [Element: Int] {
return self.reduce(into: [:]) { counts, elem in counts[elem, default: 0] += 1 }
}
}