Histogram of Array in Swift

前端 未结 2 1484
清歌不尽
清歌不尽 2021-01-21 07:32

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

相关标签:
2条回答
  • 2021-01-21 08:08

    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.

    0 讨论(0)
  • 2021-01-21 08:16

    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 }
        }
    }
    
    0 讨论(0)
提交回复
热议问题