Check if key exists in dictionary of type [Type:Type?]

后端 未结 6 1795
时光说笑
时光说笑 2020-12-03 09:48

How can I check if a key exists in a dictionary? My dictionary is of type [Type:Type?].

I can\'t simply check dictionary[key] == nil, as th

相关标签:
6条回答
  • 2020-12-03 10:10

    Actually your test dictionary[key] == nil can be used to check if a key exists in a dictionary. It will not yield true if the value is set to 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
    

    To distinguish between "key is not present in dict" and "value for key is nil" you can do a nested optional assignment:

    if let val = dict["key"] {
        if let x = val {
            println(x)
        } else {
            println("value is nil")
        }
    } else {
        println("key is not present in dict")
    }
    
    0 讨论(0)
  • 2020-12-03 10:11

    Try this:

    let value = dict[key] != nil
    

    Hope it work for you. Thanks

    0 讨论(0)
  • 2020-12-03 10:11

    As suggested here and above, the best solution is to use Dictionary.index(forKey:) which returns Dictionary<Key, Value>.Index?. Regardless of whether your value is an optional type, this returns an optional index, which if nil, definitively tells you whether the key exists in the dictionary or not. This is much more efficient than using Dictionary.contains(where:) which is documented to have "complexity O(n), where n is the length of the sequence."

    So, a much better way to write .containsKey() would be:

    extension Dictionary {
      func contains(key: Key) -> Bool {
        self.index(forKey: key) != nil
      }
    }
    

    I've been advised that dict.keys.contains() is actually O(1), so feel free to use it if you prefer.

    0 讨论(0)
  • 2020-12-03 10:22

    You can always do:

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

    However I really dislike the idea of creating an NSDictionary which can contain optionals.

    0 讨论(0)
  • 2020-12-03 10:23

    I handled it this way in Swift 4:

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

    This uses Dictionary.contains(where: (key: Hashable, value: Value) throws -> Bool). By encapsulating it as an extension I have a good shot at updating the implementation to something better without modifying my code. I'm avoiding creating data, which index(forKey:Key) does. I'm hoping it's more efficient than accessing keys since that must create the whole array before searching it.

    0 讨论(0)
  • 2020-12-03 10:26

    I believe the Dictionary type's indexForKey(key: Key) is what you're looking for. It returns the index for a given key, but more importantly for your proposes, it returns nil if it can't find the specified key in the dictionary.

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

    Swift 3 syntax....

    if dictionary.index(forKey: "someKey") == nil {
        print("the key 'someKey' is NOT in the dictionary")
    }
    
    0 讨论(0)
提交回复
热议问题