如何合并两个词典,包括唯一值

时间:2016-03-29 09:29:16

标签: ios swift dictionary

我应该如何合并两个字典来接收包含已更改值或唯一值的字典?我尝试使用字典扩展,但我只收到两者结合的合并字典。

输入和输出数据的示例如下所示。

示例:

extension Dictionary {
    mutating func mergeOptions<K, V>(dict: [K: V]){
        for (k, v) in dict {
            self.updateValue(v as! Value, forKey: k as! Key)
        }
    }
}

输入数据:

var defaultOptions = ["Content": true, "Authentication": false, "Prefix": "buu", "Database": true]

let updatedOptions = ["Content": true, "Authentication": true, "Prefix": "ua", "Database": false, "CP": true]

首选输出:

var output = ["Authentication": true, "Prefix": "ua", "Database": false, "CP": true]

4 个答案:

答案 0 :(得分:3)

这有用吗?

extension Dictionary where Value: Equatable {
    mutating func mergeOptions(dict: [Key: Value]) {
        for (k, v) in dict {
            if self[k] == nil || self[k] != v {
                self[k] = v
            } else if self[k] == v {
                self.removeValueForKey(k)
            }
        }
    }
}

var defaultOptions = ["Content": true, "Authentication": false, "Prefix": "buu", "Database": true]
let updatedOptions = ["Content": true, "Authentication": true, "Prefix": "ua", "Database": false, "CP": true]

defaultOptions.mergeOptions(updatedOptions)
print(defaultOptions) // ["Database": 0, "Prefix": ua, "Authentication": 1, "CP": 1]

请注意,这些词典的类型为[String: NSObject],这就是为什么布尔值打印为0和1而不是真和假。

答案 1 :(得分:1)

由于字典只是存储唯一键和关联值,因此您只需添加尚未成为字典一部分的所有值,并覆盖键已存在的所有其他值,以防值不同;否则删除键的值(但将指定键的值设置为nil)。这可以像下面这样轻松完成:

extension Dictionary where Value: Equatable {
    mutating func mergeOptions(newOptions: [Key: Value]) {
        for (key, value) in newOptions {
            if let selfValue = self[key] where selfValue == value {
                self[key] = nil
            } else {
                self[key] = value
            }
        }
    }
}

请注意,我使用字典本身的泛型参数(而不是函数的额外通用参数),这是必要的,当然也是您希望使用Swift的类型安全性。

答案 2 :(得分:1)

另一种方法是使用reduce(我只想尝试一下):

extension Dictionary where Value: Equatable {
    func reduceToUpdatedValuesOnly(newDictionary: [Key: Value]) -> [Key: Value] {
        return newDictionary.reduce([Key: Value]()) {
            if self[$1.0] == nil || self[$1.0]! != $1.1 {
                var dict = $0
                dict.updateValue($1.1, forKey: $1.0)
                return dict
            }
            return $0
        }
    }
}    

defaultOptions.reduceToUpdatedValuesOnly(updatedOptions)

你也可以这样做(如果你只需要做一次或两次):

updatedOptions.reduce([Key: Value]()) {
    if defaultOptions[$1.0] == nil || defaultOptions[$1.0]! != $1.1 {
         var dict = $0
         dict.updateValue($1.1, forKey: $1.0)
         return dict
    }
    return $0
}

答案 3 :(得分:1)

试试这个,它对我有用。

private Binding<bool, bool> testBinding;

// Set test binding
testBinding = this.SetBinding (
    () => Vm.Test,
    () => TestIndicator.Hidden));