Ustalenie, czy Słownik Swift zawiera klucz i uzyskanie którejkolwiek z jego wartości

Obecnie używam następujących (niezgrabnych) fragmentów kodu do określenia, czy (niepusty) Słownik Swift zawiera dany klucz i do uzyskania jednej (dowolnej) wartości z tego samego słownika.

Jak można to ująć bardziej elegancko w 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

Nie potrzebujesz żadnego specjalnego kodu, aby to zrobić, ponieważ słownik już to robi. Kiedy pobierasz dict[key], wieszczy Słownik zawiera klucz, ponieważ opcja, którą otrzymujesz, nie jest nil (i zawiera wartość).

Więc jeślipo prostu chcesz odpowiedzieć na pytanie, czy Słownik zawiera klucz, Zadaj pytanie:

let keyExists = dict[key] != nil

Jeśli chcesz wartość i wiesz Słownik zawiera klucz, powiedz:

let val = dict[key]!

Ale jeśli, Jak to zwykle bywa, nie wiesz, że zawiera klucz - chcesz go pobrać i użyć, ale tylko jeśli istnieje-użyj czegoś w stylu 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/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-05 11:23:37

Dlaczego po prostu nie sprawdzić dict.keys.contains(key)? Sprawdzanie dict[key] != nil nie będzie działać w przypadkach, gdy wartość jest nil. Jak np. w słowniku [String: String?].

 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/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-20 14:52:32

Zaakceptowana odpowiedź let keyExists = dict[key] != nil nie będzie działać, jeśli Słownik zawiera klucz, ale ma wartość nil.

Jeśli chcesz mieć pewność, że słownik w ogóle nie zawiera klucza, użyj tego (testowanego w 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/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-12 14:24:31

Wygląda na to, że masz to, czego potrzebujesz od @ matt, ale jeśli chcesz szybko uzyskać wartość dla klucza, lub tylko pierwszą wartość, jeśli ten klucz nie istnieje:

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”}

Uwaga, nie ma gwarancji, co otrzymasz jako pierwszą wartość, po prostu zdarza się w tym przypadku, aby zwrócić "red".

 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/doraprojects.net/template/agent.layouts/content.php on line 54
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/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-06 21:15:11

Moje rozwiązanie dla implementacji pamięci podręcznej, która przechowuje opcjonalne NSAttributedString:

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/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-27 12:53:31

Oto, co działa dla mnie na 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/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-31 13:09:10