如何将项目词典添加到另一个词典中

rus*_*elf 165 dictionary swift

Swift中的数组支持+ =运算符,将一个数组的内容添加到另一个数组.有没有一种简单的方法来为字典做到这一点?

例如:

var dict1 = ["a" : "foo"]
var dict2 = ["b" : "bar"]

var combinedDict = ... (some way of combining dict1 & dict2 without looping)
Run Code Online (Sandbox Code Playgroud)

小智 168

您可以定义+=运算符Dictionary,例如,

func += <K, V> (left: inout [K:V], right: [K:V]) { 
    for (k, v) in right { 
        left[k] = v
    } 
}
Run Code Online (Sandbox Code Playgroud)

  • @animal_chin因为我们必须自己实现一半的语言?是.印象深刻.不要误会我的意思我喜欢运营商超载.我只是不喜欢将它用于应该内置的基本功能. (47认同)
  • 更多语法糖:`func + = <K,V>(左上:[K:V],右:[K:V]){for(k,v)in right {left [k] = v}}` (14认同)
  • 从[SwifterSwift库]直拉(https://github.com/SwifterSwift/SwifterSwift):```公共静态功能+ =(LHS:INOUT [关键:值],RHS:[关键:值]){RHS .forEach({lhs [$ 0] = $ 1})}``` (6认同)
  • @devios哈哈然后对Swift回购提出了拉动请求:D显然苹果不能被诅咒 (2认同)

jas*_*ori 89

怎么样

dict2.forEach { (k,v) in dict1[k] = v }
Run Code Online (Sandbox Code Playgroud)

这将dict2的所有键和值添加到dict1中.

  • 好的解决方案 略短:dict2.forEach {dict1 [$ 0] = $ 1} (41认同)

Vin*_*oil 86

在Swift 4中,应该使用merging(_:uniquingKeysWith:):

例:

let dictA = ["x" : 1, "y": 2, "z": 3]
let dictB = ["x" : 11, "y": 22, "w": 0]

let resultA = dictA.merging(dictB, uniquingKeysWith: { (first, _) in first })
let resultB = dictA.merging(dictB, uniquingKeysWith: { (_, last) in last })

print(resultA) // ["x": 1, "y": 2, "z": 3, "w": 0]
print(resultB) // ["x": 11, "y": 22, "z": 3, "w": 0]
Run Code Online (Sandbox Code Playgroud)

  • //可变: var dictA = ["x" : 1, "y": 2, "z": 3] var dictB = ["x" : 11, "y": 22, "w": 0] dictA. merge(dictB, uniquingKeysWith: { (first, _) in first }) print(dictA) // ["x": 1, "y": 2, "z": 3, "w": 0] (2认同)

Rod*_*Rod 76

目前,查看Swift Standard Library Reference for Dictionary,没有办法轻松地用另一个字典更新字典.

您可以编写扩展来执行此操作

var dict1 = ["a" : "foo"]
var dict2 = ["b" : "bar"]

extension Dictionary {
    mutating func update(other:Dictionary) {
        for (key,value) in other {
            self.updateValue(value, forKey:key)
        }
    }
}

dict1.update(dict2)
// dict1 is now ["a" : "foo", "b" : "bar]
Run Code Online (Sandbox Code Playgroud)

  • 这是对Dictionary的扩展的很好用! (3认同)

sam*_*ize 69

Swift 4提供merging(_:uniquingKeysWith:),所以对于你的情况:

let combinedDict = dict1.merging(dict2) { $1 }
Run Code Online (Sandbox Code Playgroud)

简写闭包返回$1,因此当与键冲突时将使用dict2的值.


myt*_*thz 31

它没有内置到Swift库中,但您可以通过运算符重载添加所需的内容,例如:

func + <K,V>(left: Dictionary<K,V>, right: Dictionary<K,V>) 
    -> Dictionary<K,V> 
{
    var map = Dictionary<K,V>()
    for (k, v) in left {
        map[k] = v
    }
    for (k, v) in right {
        map[k] = v
    }
    return map
}
Run Code Online (Sandbox Code Playgroud)

这会使+Dictionaries 的运算符重载,您现在可以使用它来添加+运算符的字典,例如:

var dict1 = ["a" : "foo"]
var dict2 = ["b" : "bar"]

var dict3 = dict1 + dict2 // ["a": "foo", "b": "bar"]
Run Code Online (Sandbox Code Playgroud)

  • 你可以取消`map`并删除第一个`for(k,v)...`循环,如果你将`left`参数声明为`var`然后只是将`right`中的值复制到它中. (3认同)
  • @NateCook会改变字典,这对于`+`infix运算符来说不是预期的行为. (2认同)
  • @mythz它并没有真正变异,因为`+`运算符重载不是`Dictionary`的方法,它是一个简单的函数.您对变量`left`参数所做的更改在函数外部将不可见. (2认同)

小智 27

斯威夫特3:

extension Dictionary {

    mutating func merge(with dictionary: Dictionary) {
        dictionary.forEach { updateValue($1, forKey: $0) }
    }

    func merged(with dictionary: Dictionary) -> Dictionary {
        var dict = self
        dict.merge(with: dictionary)
        return dict
    }
}

let a = ["a":"b"]
let b = ["1":"2"]
let c = a.merged(with: b)

print(c) //["a": "b", "1": "2"]
Run Code Online (Sandbox Code Playgroud)

  • 更好的`func merged(使用字典:Dictionary <Key,Value>) - > Dictionary <Key,Value> {``var copy = self`` dictionary.forEach {copy.updateValue($ 1,forKey:$ 0)}`` return copy``}` (6认同)

小智 16

Swift 2.0

extension Dictionary {

    mutating func unionInPlace(dictionary: Dictionary) {
        dictionary.forEach { self.updateValue($1, forKey: $0) }
    }

    func union(var dictionary: Dictionary) -> Dictionary {
        dictionary.unionInPlace(self)
        return dictionary
    }
}
Run Code Online (Sandbox Code Playgroud)

  • var params已被弃用,将在Swift 3中删除.现在首选的方法是在body中声明var:`var dictionary = dictionary`.从这里:https://github.com/apple/swift-evolution/blob/master/proposals/0003-remove-var-parameters.md (2认同)

ric*_*ira 12

不可变

我更喜欢将不可变字典与+运算符组合在一起,所以我实现了它:

// Swift 2
func + <K,V> (left: Dictionary<K,V>, right: Dictionary<K,V>?) -> Dictionary<K,V> {
    guard let right = right else { return left }
    return left.reduce(right) {
        var new = $0 as [K:V]
        new.updateValue($1.1, forKey: $1.0)
        return new
    }
}

let moreAttributes: [String:AnyObject] = ["Function":"authenticate"]
let attributes: [String:AnyObject] = ["File":"Auth.swift"]

attributes + moreAttributes + nil //["Function": "authenticate", "File": "Auth.swift"]    
attributes + moreAttributes //["Function": "authenticate", "File": "Auth.swift"]
attributes + nil //["File": "Auth.swift"]
Run Code Online (Sandbox Code Playgroud)

易变的

// Swift 2
func += <K,V> (inout left: Dictionary<K,V>, right: Dictionary<K,V>?) {
    guard let right = right else { return }
    right.forEach { key, value in
        left.updateValue(value, forKey: key)
    }
}

let moreAttributes: [String:AnyObject] = ["Function":"authenticate"]
var attributes: [String:AnyObject] = ["File":"Auth.swift"]

attributes += nil //["File": "Auth.swift"]
attributes += moreAttributes //["File": "Auth.swift", "Function": "authenticate"]
Run Code Online (Sandbox Code Playgroud)

  • 我不明白为什么默认情况下没有内置swift? (5认同)

Vin*_*mar 12

现在不需要任何字典扩展.Swift(Xcode 9.0+)字典有一个功能.看看这里.下面是一个如何使用它的示例

  var oldDictionary = ["a": 1, "b": 2]
  var newDictionary = ["a": 10000, "b": 10000, "c": 4]

  oldDictionary.merge(newDictionary) { (oldValue, newValue) -> Int in
        // This closure return what value to consider if repeated keys are found
        return newValue 
  }
  print(oldDictionary) // Prints ["b": 10000, "a": 10000, "c": 4]
Run Code Online (Sandbox Code Playgroud)

  • 我为上面的例子添加了一个函数样式:`oldDictionary.merge(newDictionary) { $1 }` (2认同)

小智 11

你可以试试这个

var dict1 = ["a" : "foo"]
var dict2 = ["b" : "bar"]

var temp = NSMutableDictionary(dictionary: dict1);
temp.addEntriesFromDictionary(dict2)
Run Code Online (Sandbox Code Playgroud)


ork*_*den 11

使用扩展名的更易读的变体.

extension Dictionary {    
    func merge(dict: Dictionary<Key,Value>) -> Dictionary<Key,Value> {
        var mutableCopy = self        
        for (key, value) in dict {
            // If both dictionaries have a value for same key, the value of the other dictionary is used.           
            mutableCopy[key] = value 
        }        
        return mutableCopy
    }    
}
Run Code Online (Sandbox Code Playgroud)

  • 非常好,干净的解决方案! (3认同)

far*_*adf 10

您还可以使用reduce来合并它们.在操场上试一试

let d1 = ["a":"foo","b":"bar"]
let d2 = ["c":"car","d":"door"]

let d3 = d1.reduce(d2) { (var d, p) in
   d[p.0] = p.1
   return d
}
Run Code Online (Sandbox Code Playgroud)


Jus*_*roz 7

我推荐SwifterSwift库.但是,如果您不想使用整个库及其所有强大的附加功能,您可以使用它们的Dictionary扩展:

Swift 3+

public extension Dictionary {
    public static func +=(lhs: inout [Key: Value], rhs: [Key: Value]) {
        rhs.forEach({ lhs[$0] = $1})
    }
}
Run Code Online (Sandbox Code Playgroud)


Joh*_*ery 6

Swift 4 的一些更精简的重载:

extension Dictionary {
    static func += (lhs: inout [Key:Value], rhs: [Key:Value]) {
        lhs.merge(rhs){$1}
    }
    static func + (lhs: [Key:Value], rhs: [Key:Value]) -> [Key:Value] {
        return lhs.merging(rhs){$1}
    }
}
Run Code Online (Sandbox Code Playgroud)


Leo*_*onS 5

您可以迭代要合并的值的键值组合,并通过updateValue(forKey :)方法添加它们:

dictionaryTwo.forEach {
    dictionaryOne.updateValue($1, forKey: $0)
}
Run Code Online (Sandbox Code Playgroud)

现在,dictionaryTwo的所有值都被添加到dictionaryOne中.


Bur*_*lek 5

不再需要扩展或任何额外的功能。你可以这样写:

firstDictionary.merge(secondDictionary) { (value1, value2) -> AnyObject in
        return object2 // what you want to return if keys same.
    }
Run Code Online (Sandbox Code Playgroud)