Determinar si el diccionario Swift contiene la clave y obtener cualquiera de sus valores


Actualmente estoy usando las siguientes piezas de código (torpes) para determinar si un diccionario Swift (no vacío) contiene una clave dada y para obtener un valor (cualquiera) del mismo diccionario.

¿Cómo se puede poner esto más elegantemente en Swift?

// excerpt from method that determines if dict contains key
if let _ = dict[key] {
    return true
}
else {
    return false
}

// excerpt from method that obtains first value from dict
for (_, value) in dict {
    return value
}
Author: Drux, 2015-01-24

7 answers

No necesitas ningún código especial para hacer esto, porque es lo que ya hace un diccionario. Cuando obtiene dict[key] sabe si el diccionario contiene la clave, porque el Opcional que obtiene no es nil (y contiene el valor).

Entonces, si solo quieres responder la pregunta si el diccionario contiene la clave, pregunta:

let keyExists = dict[key] != nil

Si quieres el valor y sabes el diccionario contiene la clave, diga:

let val = dict[key]!

Pero si, como suele suceder, no sabes que contiene la clave-quieres recuperarla y usarla, pero solo si existe - entonces usa algo como if let:

if let val = dict[key] {
    // now val is not nil and the Optional has been unwrapped, so use it
}
 362
Author: matt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-12-05 11:23:37

¿por Qué no simplemente comprobar dict.keys.contains(key)? Comprobar dict[key] != nil no funcionará en los casos en que el valor sea nil. Como con un diccionario [String: String?] por ejemplo.

 27
Author: Hans Terje Bakke,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-06-20 14:52:32

La respuesta aceptada let keyExists = dict[key] != nil no funcionará si el Diccionario contiene la clave pero tiene un valor de nil.

Si desea asegurarse de que el Diccionario no contiene la clave en absoluto, use esto (probado en Swift 4).

if dict.keys.contains(key) {
  // contains key
} else { 
  // does not contain key
}
 11
Author: bergy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-12 14:24:31

Parece que obtuviste lo que necesitas de @ matt, pero si quieres una forma rápida de obtener un valor para una clave, o solo el primer valor si esa clave no existe:

extension Dictionary {
    func keyedOrFirstValue(key: Key) -> Value? {
        // if key not found, replace the nil with 
        // the first element of the values collection
        return self[key] ?? first(self.values)
        // note, this is still an optional (because the
        // dictionary could be empty)
    }
}

let d = ["one":"red", "two":"blue"]

d.keyedOrFirstValue("one")  // {Some "red"}
d.keyedOrFirstValue("two")  // {Some "blue"}
d.keyedOrFirstValue("three")  // {Some "red”}

Tenga en cuenta, no garantiza lo que realmente obtendrá como el primer valor, solo sucede en este caso para devolver "rojo".

 5
Author: Airspeed Velocity,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-01-24 20:02:23
if dictionayTemp["quantity"] != nil
    {

  //write your code
    }
 1
Author: Paresh Hirpara,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-09-06 21:15:11

Mi solución para una implementación de caché que almacena NSAttributedString opcional:

public static var attributedMessageTextCache    = [String: NSAttributedString?]()

    if attributedMessageTextCache.index(forKey: "key") != nil
    {
        if let attributedMessageText = TextChatCache.attributedMessageTextCache["key"]
        {
            return attributedMessageText
        }
        return nil
    }

    TextChatCache.attributedMessageTextCache["key"] = .some(.none)
    return nil
 0
Author: Rishi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-07-27 12:53:31

Esto es lo que funciona para mí en Swift 3

let _ = (dict[key].map { $0 as? String } ?? "")
 0
Author: ΩlostA,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-07-31 13:09:10