2016-01-23 2 views
3

Я работаю со сложным словарем и хочу упростить работу, просто назначив ему переменную.Как назначить ссылку на словарь в Swift

myDictionay["with"]["complex"]["sub"]["dictionary"] = "NewValue" 

Я просто хочу, чтобы это:

let smaller = myDictionay["with"]["complex"]["sub"] 
smaller["dictionary"] = "NewValue" 

Как я могу это сделать?

+1

@PetahChristian Это не дубликаты. Он спрашивает, как определить указатель на переменную. –

ответ

1

Вы можете использовать замыкание, чтобы выполнить внутренний доступ для вас:

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 
2

Свифт DictionaryArray/Set) следует пройти по справочным семантике, а не передавать семантикой значения (если вы посмотрите в заголовках, вы увидите, что это struct, а не class). Это означает, что при назначении экземпляра Dictionary из одной переменной в другую переменную и изменении значения, связанного с новой переменной, оно не фактически меняет значение, связанное с исходным значением. Таким образом, синтаксис, который вы ищете, невозможен с помощью Swift Dictionary. Сказав это, вы всегда можете использовать NSMutableDictionary, а затем синтаксис, на который вы надеетесь, будет работать.

Смежные вопросы