Проверьте, существует ли ключ в словаре типа [Тип: Тип?]

Как проверить, существует ли ключ в словаре? Мой словарь имеет тип [Type:Type?].

Я не могу просто проверить dictionary[key] == nil, поскольку это может быть результатом значения nil.

Любые идеи?

Ответ 1

На самом деле ваш тест dictionary[key] == nil можно использовать для проверки если в словаре существует ключ. Он не даст true, если значение установлен на nil:

let dict : [String : Int?] = ["a" : 1, "b" : nil]

dict["a"] == nil // false,     dict["a"] is .Some(.Some(1))
dict["b"] == nil // false !!,  dict["b"] is .Some(.None)
dict["c"] == nil // true,      dict["c"] is .None

Чтобы различать "ключ отсутствует в dict", а "значение для ключа - это nil", вы может выполнять вложенное необязательное назначение:

if let val = dict["key"] {
    if let x = val {
        println(x)
    } else {
        println("value is nil")
    }
} else {
    println("key is not present in dict")
}

Ответ 2

Я считаю, что тип словаря indexForKey(key: Key) - это то, что вы ищете. Он возвращает индекс для заданного ключа, но что более важно для ваших предложений, он возвращает nil, если он не может найти указанный ключ в словаре.

if dictionary.indexForKey("someKey") != nil {
    // the key exists in the dictionary
}

Синтаксис Swift 3....

if dictionary.index(forKey: "someKey") == nil {
    print("the key 'someKey' is NOT in the dictionary")
}

Ответ 3

Вы всегда можете сделать:

let arrayOfKeys = dictionary.allKeys
if (arrayOfKeys.containsObject(yourKey)) {

}
else {
}

Однако мне действительно не нравится идея создания NSDictionary, которая может содержать дополнительные опции.

Ответ 4

Попробуйте следующее:

let value = dict[key] != nil

Надеюсь, он сработает для вас. Благодаря

Ответ 5

Я обработал его таким образом в Swift 4:

extension Dictionary {
    func contains(key: Key) -> Bool {
        let value = self.contains { (k,_) -> Bool in key == k }
        return value
    }
}

В этом случае используется Dictionary.contains(where: (key: Hashable, value: Value) throws -> Bool). Инкапсулируя его как расширение, у меня есть хороший шанс обновить реализацию до чего-то лучшего без изменения моего кода. Я избегаю создания данных, которые index(forKey:Key) делает. Я надеюсь, что это будет более эффективным, чем доступ к keys, поскольку для этого нужно создать весь массив.

Ответ 6

Это работает для меня [Swift 3.0]:

let myVar = "c"
let myDict: [String: Int] = ["a": 0, "b": 1, "c": 2]
if myDict.keys.contains(myVar) {
   print(myVar)
} else {
   print("ERROR")
}