Como verificar se uma chave existe em um dicionário Swift e obter o valor: guia completo para iniciantes e profissionais
\n\nTrabalhar com dicionários é o pão de cada dia de todo desenvolvedor iOS. Mas quando passamos do simples "inserir um valor" para "será que essa chave existe?" — começam os desafios. Essa pergunta já acumulou milhares de visualizações no Stack Overflow, e não é à toa: uma tarefa aparentemente simples esconde várias armadilhas.
\n\nNeste artigo, não vamos apenas responder à pergunta "Determining if Swift dictionary contains key and obtaining any of its values", mas vamos detalhar 5 abordagens diferentes. Você descobrirá qual método é mais rápido, qual é mais seguro e qual é simplesmente um código elegante, gostoso de escrever e ler.
\n\nBreve introdução: o que é Dictionary no Swift?
\n\nPara quem está começando com Swift: Dictionary é uma coleção de pares "chave-valor". As chaves são únicas, os valores podem se repetir. Funciona assim:
var pontuacoesUsuarios: [String: Int] = [\n "Alice": 95,\n "Bob": 87,\n "Charlie": 92\n]\n\nAgora imagine: você quer obter a pontuação do jogador "David". Mas David não está no dicionário. Se você simplesmente escrever pontuacoesUsuarios["David"], o Swift não vai quebrar, mas vai retornar nil. E é aí que a coisa fica interessante.
Método nº1: O clássico if let — a base que todo mundo precisa saber
\n\nA maneira mais simples e legível é usar o optional binding com if let. Você verifica se a chave existe e já obtém o valor ao mesmo tempo:
let pontuacoes: [String: Int] = ["Alice": 95, "Bob": 87]\n\nif let pontuacaoAlice = pontuacoes["Alice"] {\n print("Pontuação da Alice: \\(pontuacaoAlice)")\n} else {\n print("Jogador não encontrado")\n}\n\nVantagens:
\n- \n
- Código extremamente legível \n
- Trabalho seguro com opcionais \n
- Não precisa chamar métodos adicionais \n
Desvantagens:
\n- \n
- Se você só precisa verificar se a chave existe, sem obter o valor, é um pouco exagerado \n
Essa abordagem é o padrão ouro para 90% dos casos. É exatamente o que a documentação oficial da Apple recomenda.
\n\nMétodo nº2: Guard let — para saída antecipada de funções
\n\nSe você está escrevendo uma função onde a ausência da chave é motivo para sair imediatamente, use guard let. Isso mantém o código linear e evita a "pirâmide da morte" de ifs aninhados:
func exibirPontuacao(do jogador: String, em pontuacoes: [String: Int]) {\n guard let pontuacao = pontuacoes[jogador] else {\n print("Jogador \\(jogador) não encontrado")\n return\n }\n // Aqui temos certeza que pontuacao existe\n print("Pontuação do jogador \\(jogador): \\(pontuacao)")\n}\n\nexibirPontuacao(do: "Bob", em: ["Alice": 95, "Bob": 87]) // Pontuação do jogador Bob: 87\nexibirPontuacao(do: "David", em: ["Alice": 95, "Bob": 87]) // Jogador David não encontrado\n\nVantagens:
\n- \n
- Separação clara entre "caminho de erro" e "cenário principal" \n
- A variável fica disponível em todo o escopo após o guard \n
Desvantagens:
\n- \n
- Não é adequado se você só quer verificar a existência sem sair da função \n
Método nº3: Verificação com contains(where:) — quando a chave pode ser complexa
\n\nÀs vezes você não quer apenas encontrar uma chave, mas verificá-la com base em alguma condição. Por exemplo, a chave é uma string e você busca uma correspondência parcial. É aí que entra o método contains(where:):
\n\nlet config: [String: Any] = [\n "app_version": "2.1.0",\n "build_number": 42,\n "is_debug_mode": true\n]\n\n// Procurando uma chave que começa com "app_"\nlet temChaveApp = config.keys.contains { $0.hasPrefix("app_") }\nprint("Tem chave app_: \\(temChaveApp)") // true\n\n// Obtendo o valor da primeira chave encontrada\nif let chaveApp = config.keys.first(where: { $0.hasPrefix("app_") }) {\n print("Valor: \\(config[chaveApp] ?? "nil")")\n}