Вы можете использовать замыкание, чтобы выполнить внутренний доступ для вас:
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"]]]] */
Или, более конденсируется: вы можете использовать замыкание специально со словарем имя доступного в области видимости, где используется закрытие (то есть, нет необходимости отправлять ссылку на словарь в качестве аргумента для закрытия).
let smaller2 : (String, String) ->() = { myDictionary["with"]?["complex"]?["sub"]?[$0] = $1 }
smaller2("dictionary", "NewerValue")
print(myDictionary)
/* ["with": ["complex": ["anothersub": ["dictionary": "OldValue"],
"sub": ["dictionary": "NewerValue"]]]] */
Если вы обработка вашего словаря 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"]]]] */
выше предполагает словарь ключевых путей трех уровней ("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
@PetahChristian Это не дубликаты. Он спрашивает, как определить указатель на переменную. –