Swift:在数组中组合字典

时间:2015-01-20 04:19:13

标签: arrays swift dictionary

我正在寻找一种优雅的方式来组合一系列词典。

Input: [[a: foo], [b: bar], [c: baz]]
Output: [a: foo, b: bar, c: baz]

实现这一目标的最佳方式是什么?

8 个答案:

答案 0 :(得分:5)

您可以使用reduce,但您必须定义一个“合并”方法,该方法可以为您提供来自2个单独词典的组合词典。

所以你可以做这样的事情

let inputArray = [["a": "foo"], ["b": "bar"], ["c": "baz"], ["c": "bazx"]]
let flat = inputArray.reduce([:]) { $0 + $1 }

如果你在词典

上重载了“+”
func + <K, V>(lhs: [K : V], rhs: [K : V]) -> [K : V] {
    var combined = lhs

    for (k, v) in rhs {
        combined[k] = v
    }

    return combined
}

答案 1 :(得分:2)

我会使用Dictionary扩展程序:

extension Dictionary {
    init<S: SequenceType where Element == S.Generator.Element>(_ s:S) {
        self.init()
        var g = s.generate()
        while let e: Element = g.next() {
            self[e.0] = e.1
        }
    }
}

使用此扩展程序,您可以使用Dictionary对序列初始化(Key, Value)。所以你可以:

let input = [["a": "foo"], ["b": "bar"], ["c": "baz"]]

let output = Dictionary(input.reduce([], { $0 + $1 }))

答案 2 :(得分:1)

let inputArray = [["a": "foo"], ["b": "bar"], ["c": "baz"]].reduce([], +)
var result:[String:String] = [:]
for item in inputArray {
    result.updateValue(item.1, forKey: item.0)
}
println(result.description)

答案 3 :(得分:1)

let inputArray = [["a": "foo"], ["b": "bar"], ["c": "baz"], ["c": "bazx"]]

var flat = [String:String]()
for e in inputArray {
    for (k, v) in e {
        flat[k] = v
    }
}

dump(flat)

答案 4 :(得分:1)

这不是一个可怕的解决方案......

let inputArray = [["a": "foo"], ["b": "bar"], ["c": "baz"]]

let inputArrayFlat = inputArray.reduce([String:String]()) {
    var output = $0
    for (key, value) in $1 { output[key] = value }
    return output
}

答案 5 :(得分:1)

使用 Swift 4.2 的另一种方法:

let inputArray = [["a": "foo"], ["b": "bar"], ["c": "baz"], ["c": "bazx"]]
let result = inputArray.flatMap { $0 }.reduce([:]) { $0.merging($1) { (current, _) in current } }

输出:

["b": "bar", "c": "baz", "a": "foo"]

答案 6 :(得分:0)

你可以在外部数组上使用reduce两次,在内部字典上使用一次,然后处理它们。如果任何词典具有重复键,则此版本将仅保留该键的最后一个值。

func flattenDictionaryList<T, U>(list: [[T: U]]) -> [T: U] {
    return list.reduce([:]) { combined, current in
        reduce(current, combined) { (var innerCombined: [T: U], innerCurrent: (key: T, value: U)) in
            innerCombined[innerCurrent.key] = innerCurrent.value
            return innerCombined
        }
    }
}

let input = [["a": "foo"], ["b": "bar"], ["c": "baz"]]
let output = flattenDictionaryList(input)

答案 7 :(得分:0)

将一系列词典合并到一个字典中,用新键覆盖重复的现有键。

[[String:String]]变成单个[String:String]

extension Array where Element == [String:String] {

    func merged() -> [String:String] {
        return reduce(into: [String:String]()) {
            $0.merge($1) { (_, new) in new }
        }
    }

}

我想要一个不依赖String的通用版本,但是很难将其表达给编译器。如果有人想尝试一下,请编辑或评论。