Find a single key containing a string in a swift dictionary

I have a dictionary [String:String] . I would like to get the value associated with any key containing the string "S". The order does not matter.

This is dead easy: just get all the keys, iterations, return the first match with the condition.

HOWEVER, I would like to do this using a quick approach similar to elegant. Something using the filter or map functions. And this is where I get lost ...

+7
dictionary swift
source share
3 answers

Since you are only interested in the corresponding value, you can use the indexOf() method to find the first dictionary match. This works because a dictionary is a collection of key / value pairs.

Swift 2:

 let dict = ["foo": "bar", "PQRS": "baz"] let searchTerm = "S" if let index = dict.indexOf({ (key, _) in key.containsString(searchTerm) }) { let value = dict[index].1 print(value) } else { print("no match") } 

As soon as the corresponding key is found, the predicate returns true and the enumeration stops. index is a "dictionary index" that can be used directly to get the corresponding entry in the dictionary.

To search for a case-insensitive keyword, replace the predicate with

 { (key, _) in key.rangeOfString(searchTerm, options: .CaseInsensitiveSearch) != nil } 

In Swift 3, you can use first(where:) to find the first match of an element, this saves one search in the dictionary:

 if let entry = dict.first(where: { (key, _) in key.contains(searchTerm) }) { print(entry.value) } else { print("no match") } 

To search for a case-insensitive keyword, replace the predicate with

 { (key, _) in key.range(of: searchTerm, options: .caseInsensitive) != nil } 
+9
source share

You can use filter , contains and first to search for "s":

Swift 2

 if let key = yourDictionary.keys.filter({ $0.lowercaseString.characters.contains("s") }).first, let result = yourDictionary[key] { print(result) } 

Swift 3

 if let key = yourDictionary.keys.filter({ $0.lowercased().contains("s") }).first, let result = yourDictionary[key] { print(result) } 

In @Hamish comment , this is a great alternative for Swift 3: instead

 filter({ ... }).first 

you can use

 first(where: { ... }) 

Example:

 if let key = yourDictionary.keys.first(where: { $0.lowercased().contains("s") }), let result = yourDictionary[key] { print(result) } 
+4
source share

You can do this with flatMap and containsString :

Swift 2.x :

 let dict = ["one": "1", "two": "2", "three": "3", "four": "4", "five": "5", "six": "6"] let results = dict.flatMap { (key, value) in key.lowercaseString.containsString("o") ? value : nil } print(results) 

Output:

 ["4", "1", "2"] 
 print(results.first ?? "Not found") 
 4 

Or if you like mysterious liners:

 let first = dict.flatMap { $0.lowercaseString.containsString("o") ? $1 : nil }.first ?? "Not found" 

For Swift 3 :

 let dict = ["one": "1", "two": "2", "three": "3", "four": "4", "five": "5", "six": "6"] let results = dict.flatMap { (key, value) in key.lowercased().contains("o") ? value : nil } print(results) print(results.first ?? "Not Found") 

Or if you like mysterious liners:

 let first = dict.flatMap { $0.lowercased().contains("o") ? $1 : nil }.first ?? "Not Found" 
+4
source share

All Articles