我有嵌套的字典,所以像这样:
var dict = ["a":["b":"c", "d":["e":"f"]], "f":["b":"g"]] // and more
现在,如果我想更新密钥a.d.e的值,该怎么办?
似乎updateValue方法仅按原样读取键...对嵌套键一无所知。
编辑:
虽然我确实想将这些数据的结构更改为更易于使用的结构。我不能这属于另一个类,我不允许更改结构,我所能做的就是更新它。
第二次修改:
经过一番思考并读完另一个问题,有人指出可能是重复的,尝试递归更新。我认为这是最糟糕的方法,因为从本质上讲,它正在使用原始值的副本创建新字典并将其分配回去。我确实认为这是浪费空间,并且甚至递归地调用它,我觉得这是不必要的。
func updateKey(key:[AnyHashable],val:Bool,data:[AnyHashable:Any])->[AnyHashable:Any]{
var keyTemp = key
var tempData = data
if(keyTemp.count==1){
tempData.updateValue(val, forKey: key[0])
print(tempData)
return tempData
}else{
var firstLayerValue = data[keyTemp[0]] as? [AnyHashable:Any]
var firstKey = keyTemp.removeFirst()
var tempResult = updateKey(key: keyTemp, val: val, data: firstLayerValue!)
tempData.updateValue(tempResult, forKey: firstKey)
return tempData;
}
}
这将返回我要执行的操作的副本,并且我必须将其实际分配回原始副本。我真的不喜欢这种来回分配的东西,如果中间出现问题,那我可能最终会丢失最初正确的数据。
有更好的解决方案吗?
答案 0 :(得分:1)
结构是必经之路。但是,如果您真的必须使用字典,可以采用以下解决方法:
var dict: [AnyHashable: Any] =
["a": ["b": "c", "d": ["e":"f"]],
"f": ["b": "g"]]
let newValue = true
if var firstLevel = dict["a"] as? [String : Any],
var secondLevel = firstLevel["d"] as? [String: Any] {
secondLevel["e"] = newValue
firstLevel["d"] = secondLevel
dict["a"] = firstLevel
}
print(dict) //[AnyHashable("a"): ["d": ["e": true], "b": "c"], AnyHashable("f"): ["b": "g"]]
要更新具有多个级别的字典中的值,可以定义如下函数:
func update(dictionary dict: inout [AnyHashable: Any], at keys: [AnyHashable], with value: Any) {
if keys.count < 2 {
for key in keys { dict[key] = value }
return
}
var levels: [[AnyHashable: Any]] = []
for key in keys.dropLast() {
if let lastLevel = levels.last {
if let currentLevel = lastLevel[key] as? [AnyHashable: Any] {
levels.append(currentLevel)
}
else if lastLevel[key] != nil, levels.count + 1 != keys.count {
break
} else { return }
} else {
if let firstLevel = dict[keys[0]] as? [AnyHashable : Any] {
levels.append(firstLevel )
}
else { return }
}
}
if levels[levels.indices.last!][keys.last!] != nil {
levels[levels.indices.last!][keys.last!] = value
} else { return }
for index in levels.indices.dropLast().reversed() {
levels[index][keys[index + 1]] = levels[index + 1]
}
dict[keys[0]] = levels[0]
}
并像这样使用它:
var dict: [AnyHashable: Any] = ["a": ["b": 1,
"c": ["d": ["e": "f"],
"g": ["h": 1.5]]],
"j": ["k": 2]]
update(dictionary: &dict,
at: ["a", "c", "d", "e"],
with: true)
dict.forEach { print($0) }
这是控制台中的输出:
(key: AnyHashable("a"), value: [AnyHashable("b"): 1, AnyHashable("c"): [AnyHashable("d"): [AnyHashable("e"): true], AnyHashable("g"): ["h": 1.5]]]) (key: AnyHashable("j"), value: ["k": 2])
答案 1 :(得分:1)
另一种方式
dict["a"]?["d"] = ["e": 123]
print(dict)
输出
[“ f”:[“ b”:“ g”],“ a”:[“ b”:“ c”,“ d”:[“ e”:123]]]