Swiftでassociate/associateBy

2017-01-19 07:59  -  1 min read

配列をディクショナリにする便利関数です。 Swiftになさそうなので実装してみました。

同じことをするにはreduceを駆使してやや冗長に書く必要があります。 keyかvalueになる要素がnilだった場合は要素の追加をスキップします。お好みで変えてください。

extension Array {
    func associateBy<T, U>(_ forKey: (Array.Generator.Element) -> T?,
                     _ forValue: (Array.Generator.Element) -> U?) -> [T:U] {
        return self.reduce([T:U](), { result, element in
            let key = forKey(element)
            let value = forValue(element)

            if let key = key, let value = value {
                var newResult = result
                newResult[key] = value
                return newResult
            } else {
                return result
            }
        })
    }
    
    func associate<T, U>(_ bundler: (Array.Generator.Element) -> (T?, U?)) -> [T:U] {
        return self.reduce([T:U](), { result, element in
            let bundle = bundler(element) 
            
            if let key = bundle.0, let value = bundle.1 {
                var newResult = result
                newResult[key] = value
                return newResult
            } else {
                return result
            }
        })
    }
}

使い方

let array = [("a", 100), ("b", 20), ("c", 10)]
array.associateBy({ "Key: " + $0.0 }, { 100 + $0.1 }) // => [String:Int]

array.associate { ($0.0, $0.1) } // => [String:Int]