Swift: How to remove a null value from Dictionary?
Swift 5
Use compactMapValues
:
dictionary.compactMapValues { $0 }
compactMapValues
has been introduced in Swift 5. For more info see Swift proposal SE-0218.
Example with dictionary
let json = [ "FirstName": "Anvar", "LastName": "Azizov", "Website": nil, "About": nil,]let result = json.compactMapValues { $0 }print(result) // ["FirstName": "Anvar", "LastName": "Azizov"]
Example including JSON parsing
let jsonText = """ { "FirstName": "Anvar", "LastName": "Azizov", "Website": null, "About": null } """let data = jsonText.data(using: .utf8)!let json = try? JSONSerialization.jsonObject(with: data, options: [])if let json = json as? [String: Any?] { let result = json.compactMapValues { $0 } print(result) // ["FirstName": "Anvar", "LastName": "Azizov"]}
Swift 4
I would do it by combining filter
with mapValues
:
dictionary.filter { $0.value != nil }.mapValues { $0! }
Examples
Use the above examples just replace let result
with
let result = json.filter { $0.value != nil }.mapValues { $0! }
You can create an array containing the keys whose corresponding values are nil:
let keysToRemove = dict.keys.array.filter { dict[$0]! == nil }
and next loop through all elements of that array and remove the keys from the dictionary:
for key in keysToRemove { dict.removeValueForKey(key)}
Update 2017.01.17
The force unwrapping operator is a bit ugly, although safe, as explained in the comments. There are probably several other ways to achieve the same result, a better-looking way of the same method is:
let keysToRemove = dict.keys.filter { guard let value = dict[$0] else { return false } return value == nil}
I ended up with this in Swift 2:
extension Dictionary where Value: AnyObject { var nullsRemoved: [Key: Value] { let tup = filter { !($0.1 is NSNull) } return tup.reduce([Key: Value]()) { (var r, e) in r[e.0] = e.1; return r } }}
Same answer but for Swift 3:
extension Dictionary { /// An immutable version of update. Returns a new dictionary containing self's values and the key/value passed in. func updatedValue(_ value: Value, forKey key: Key) -> Dictionary<Key, Value> { var result = self result[key] = value return result } var nullsRemoved: [Key: Value] { let tup = filter { !($0.1 is NSNull) } return tup.reduce([Key: Value]()) { $0.0.updatedValue($0.1.value, forKey: $0.1.key) } }}
Things get a lot easier in Swift 4. Just use Dictionary's filter
directly.
jsonResult.filter { !($0.1 is NSNull) }
Or if you don't want to remove the relevant keys, you can do this:
jsonResult.mapValues { $0 is NSNull ? nil : $0 }
Which will replace the NSNull
values with nil
instead of removing the keys.