Reputation: 1479
I want to convert a dictionary to an Array, by showing each [String: [String]]
element as a string in the array (but the value may be empty).
So ["A": ["1","2"], "b": [], "c": ["5", "6"]]
will give ["b", "A1", "A2", "c5", "c6"]
.
I want to use map to do this, as the code I have feels unwieldy:
let messages: [String: [String]] = ["A": ["1","2"], "b": [], "c": ["5", "6"]]
var result: [String] = []
for message in messages {
if !message.value.isEmpty {
for value in message.value {
result.append(message.key + value)
}
} else {
result.append(message.key)
}
}
How can I create the solution using map?
Upvotes: 0
Views: 195
Reputation: 26096
A possible solution is to use reduce(into:_:)
, (I prefer this one):
let messages: [String: [String]] = ["A": ["1","2"], "b": [], "c": ["5", "6"]]
let output = messages.reduce(into: [String]()) { result, current in
guard !current.value.isEmpty else { result.append(current.key); return }
let sub = current.value.map { current.key + $0 }
result.append(contentsOf: sub)
}
print("Output: \(output)")
Output: $> Output: ["c5", "c6", "A1", "A2", "b"]
With a map
and a flatMap
, I found it less intuitive:
let output2 = messages.map { element -> [String] in
guard !element.value.isEmpty else { return [element.key] }
let sub = element.value.map { element.key + $0 }
return sub
}.flatMap { $0 }
print("Output2: \(output2)")
Which then can be simplified with a direct call to flatMap
, but that (map
+ flatMap
) was to show the process, since this one will save you an iteration (you do only one instead of two):
let output3 = messages.flatMap { element -> [String] in
guard !element.value.isEmpty else { return [element.key] }
let sub = element.value.map { element.key + $0 }
return sub
}
print("Output3: \(output3)")
I made the closure explicit enough, but that's up to you if you want to shorten them with ternary if etc.
Upvotes: 1
Reputation: 760
A little bit shortened version using map
let messages: [String: [String]] = ["A": ["1","2"], "b": [], "c": ["5", "6"]]
let result = messages.map { dict in
return dict.value.isEmpty ? ["\(dict.key)"] : dict.value.map { "\(dict.key)\($0)" }
}.flatMap{$0}
Upvotes: 1