I have the following array, I have to make sure to divide it in this way into subarray, taking into consideration the first part of the name followed by / as a criterion for subdivision, for example "name/other".
Can you give me a hand?
var a = ["origin/a", "origin/b", "origin/c", "remo/a", "remo/d", "remo/c", "next/g"]
var b = {
origin: ["a", "b", "c"],
remo: ["a", "d", "c"],
next: ["g"]
}
CodePudding user response:
You could used reduce(into:_:)
to do so:
let reduced = a.reduce(into: [String: [String]]()) { partialResult, currentTerm in
let components = currentTerm.components(separatedBy: "/")
guard components.count == 2 else { return }
partialResult[components[0]] = partialResult[components[0], default: [String]()] [components[1]]
}
print(reduced)
Output:
$>["remo": ["a", "d", "c"], "next": ["g"], "origin": ["a", "b", "c"]]
CodePudding user response:
One idea is like this:
First we need to separate the keys for the dictionary and all the values that need to be gathered together:
let keysValues = a
.map { $0.components(separatedBy: "/") }
.compactMap { components -> (String, String)? in
guard components.count == 2 else { return nil }
return (components.first!, components.last!)
}
Now we need to reduce that into a dictionary of [String: [String]]
by grouping together the values for each key:
var dict: [String: [String]] = [:]
let answer = keysValues.reduce(into: dict) { (d, kv) in
let (k, v) = kv
d[k, default: []] = [v]
}