我正在寻找一种优雅的方式来组合一系列词典。
Input: [[a: foo], [b: bar], [c: baz]]
Output: [a: foo, b: bar, c: baz]
实现这一目标的最佳方式是什么?
答案 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
的通用版本,但是很难将其表达给编译器。如果有人想尝试一下,请编辑或评论。