Swift中数组的直方图

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.ElementAnyHashable,然后强迫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)

vac*_*ama 8

通用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)

  • 更简单:`让值= acc [键,默认值:0] + 1` (2认同)