gmoraleda
gmoraleda

Reputation: 1953

Map dictionary to array to string

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

Answers (1)

David Pasztor
David Pasztor

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

Related Questions