Reputation: 1953
I'm handling a dictionary which I need to parse into a string to create a property for a GraphQL mutation.
My dictionary is [String: Bool]
and I need to extract the keys set to true
.
let dict: [String: Bool] = ["Objct1": true, "Objct2": false, "Objct3": true]
Currently I'm using four functions (filter, enumerate, map and join) and, although I get the desired result, I wonder if I need all of them:
let string = dict.filter { $0.value }
.enumerated()
.map {
return $0.offset == 0
? "\"\($0.element.key)\""
: ", \"\($0.element.key)\""
}
.joined()
Edit:
The final string needs to be wrapped in "
: ""Objct1", "Objct3""
Upvotes: 0
Views: 524
Reputation: 54745
You can use a single compactMap
, since first you'd need to filter
your Dictionary
to only keep the true
values, then you'd need to map
to return the key
corresponding to the true
values. However, you can always merge consequent filter
and map
calls into a single compactMap
, since compactMap
only keeps non-nil
values, so instead of returning a boolean as you would for filter
, in case your condition evaluates to true, you return whatever you would return in map
, otherwise you return nil
.
let trueKeys = dict.compactMap({key, value in value ? key : nil})
To join the keys into a single String, you can just call joined
on the result of compactMap
.
let graphQueryString = dict.compactMap({key, value in value ? "\"\(key)\"" : nil}).joined(separator: ",") // ""Objct3","Objct1""
Keep in mind that the ordering of your keys won't necessarily be the same as you declared the Dictionary
, since Dictionary
is an unordered collection by definition. If you want to keep ordering, you can use an array of tuples instead of a Dictionary
, where the tuple will consist of the key-value pairs.
Upvotes: 4