Home > Net >  Divide array into subarrays
Divide array into subarrays

Time:08-25

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]
}
  • Related