我正在使用复杂的字典,并希望只需为其分配一个变量即可轻松工作。
myDictionay["with"]["complex"]["sub"]["dictionary"] = "NewValue"
Run Code Online (Sandbox Code Playgroud)
我只想要这个:
let smaller = myDictionay["with"]["complex"]["sub"]
smaller["dictionary"] = "NewValue"
Run Code Online (Sandbox Code Playgroud)
我该怎么做?
您可以使用闭包来为您执行内部访问:
let smaller : (inout _: [String : [String : [String :[String : String]]]], key: String, val: String) -> () = { dict, key, val in
dict["with"]?["complex"]?["sub"]?[key] = val
return ()
}
/* setup example */
var a = [String : String]()
var b = [String :[String : String]]()
var c = [String : [String : [String : String]]]()
var myDictionary = [String : [String : [String :[String : String]]]]()
a["dictionary"] = "OldValue"
b["sub"] = a
b["anothersub"] = a
c["complex"] = b
myDictionary["with"] = c
/* example */
print(myDictionary)
/* ["with": ["complex": ["anothersub": ["dictionary": "OldValue"],
"sub": ["dictionary": "OldValue"]]]] */
smaller(&myDictionary, key: "dictionary", val: "NewValue")
print(myDictionary)
/* ["with": ["complex": ["anothersub": ["dictionary": "OldValue"],
"sub": ["dictionary": "NewValue"]]]] */
Run Code Online (Sandbox Code Playgroud)
或者,更简洁:您可以专门使用带有可在使用闭包的范围内访问的字典名称的闭包(即,无需将对字典的引用作为闭包的参数发送)。
let smaller2 : (String, String) -> () = { myDictionary["with"]?["complex"]?["sub"]?[$0] = $1 }
smaller2("dictionary", "NewerValue")
print(myDictionary)
/* ["with": ["complex": ["anothersub": ["dictionary": "OldValue"],
"sub": ["dictionary": "NewerValue"]]]] */
Run Code Online (Sandbox Code Playgroud)
如果您将字典myDictionary作为某些类属性来处理,则可以作为上述方法的替代方法,定义一个返回闭包的类方法,如上面所示,给定“字典键路径”,例如"with.complex.sub",作为参数:
/* say 'myDictionary' is some class property (initialized as in example above)
In same class, introduce the following method */
func dictClosure(dictKeyPath: String) -> ((String, String) -> ()) {
let arr = dictKeyPath.componentsSeparatedByString(".")
if arr.count == 3 {
return {
myDictionary[arr[0]]?[arr[1]]?[arr[2]]?[$0] = $1 }
}
else {
return {
_, _ in
print("This closure is invalid")
}
}
}
/* example usage */
var smaller3 = dictClosure("with.complex.sub")
smaller3("dictionary", "NewestValue")
smaller3 = dictClosure("with.complex.anothersub")
smaller3("dictionary", "AlsoNewValue")
print(myDictionary)
/* ["with": ["complex": ["anothersub": ["dictionary": "AlsoNewValue"],
"sub": ["dictionary": "NewestValue"]]]] */
Run Code Online (Sandbox Code Playgroud)
上面假设字典键路径为三级 ( "one.two.three"),并生成用于访问第四级字典的闭包。
最后请注意,对于上述所有解决方案,调用smaller闭包将允许将新的键值对添加到字典的第四级中,而不仅仅是改变现有对的值。例如,键拼写错误smaller3("dcitionary", "NewValue")会将键值对添加"dcitionary": "NewValue"到第四级字典中。如果您只想允许更改现有键的值,只需?在上面的闭包中最内部的键访问后面添加smaller:
/* smaller ... */
dict["with"]?["complex"]?["sub"]?[key]? = val
/* smaller2 ... */
myDictionary["with"]?["complex"]?["sub"]?[$0]? = $1
/* smaller3 ... */
myDictionary[arr[0]]?[arr[1]]?[arr[2]]?[$0]? = $1
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1529 次 |
| 最近记录: |