James White
James White

Reputation: 784

Most efficient way to flatten an array of dictionaries containing arrays

Let's say I have an array of dictionaries, and each contains an array of letters. Like this:

let dicts = [["letters" : ["a","b","c"]],
             ["letters" : ["d","e","f"]]]

What is the most efficient way to create a flattened array of all the letters from all the dictionaries?

Upvotes: 1

Views: 1386

Answers (3)

Martin R
Martin R

Reputation: 539815

You can use flatMap() to map each dictionary to the corresponding letters array and join the results:

let dicts = [["letters" : ["a","b","c"]],
             ["letters" : ["d","e","f"]]]

let letters = Array(dicts.flatMap { $0["letters"] }.joined())
print(letters) // ["a", "b", "c", "d", "e", "f"]

This is effective insofar as no additional intermediate arrays are created during the join. As @Hamish pointed out below, the intermediate [[String]] can be avoided with

let letters = Array(dicts.lazy.flatMap { $0["letters"] }.joined())

Upvotes: 2

Nirav D
Nirav D

Reputation: 72420

You can use reduce(_:_:) for that.

let array = dicts.reduce([]) { $0 + ($1["letters"] ?? []) }
print(array) // ["a","b","c","d","e","f"]

Edit: As @Hamish suggested a link in comment simplest solution is having less time, so if you are having large amount of data then you can use forEach closure with array.

var result = [String]()
dicts.forEach {      
    result.append(contentsOf: $0["letters"] ?? [])
}

Upvotes: 2

RajeshKumar R
RajeshKumar R

Reputation: 15758

You can use any one of these. You don't need to specify the key name of the dictionary.

Solution 1

    let array = dicts.reduce([]) { $0 + ($1.values.reduce([]) { $0 + $1 }) }
    print(array) // ["a","b","c","d","e","f"]

Solution 2

    let array = dicts.flatMap { $0.values.joined() }
    print(array) // ["a","b","c","d","e","f"]

Upvotes: 1

Related Questions