Tyler
Tyler

Reputation: 19858

Flatten all values of multiple arrays in Swift

I have a Dictionary of Integer Arrays like below:

let numbers = [1: [2, 3], 4: [5, 6, 7], 8: [9]]

What I really want is a single flattened Array of all of the values (which themselves are arrays), like so:

[2, 3, 5, 6, 7, 9]

Now, I have been able to call numbers.values.array to get:

[[2, 3], [5, 6, 7], [9]]

But what I'm looking for is to merge these one step further, flattening them.

Does Swift (1.1, or 1.2) offer a convenience method for this?

Upvotes: 5

Views: 2193

Answers (3)

Jeffery Thomas
Jeffery Thomas

Reputation: 42598

This is called flattening, and it's a relatively common operation. There are a number of ways to do it, so pick one that suits your needs.

numbers.values.array.reduce([], combine: +) // As stated by @Bluehound
reduce(numbers.values, [], +)
numbers.values.array.flatMap { $0 } // Swift 1.2 (Xcode 6.3)
flatMap(numbers.values) { $0 } // Swift 1.2 (Xcode 6.3)

flatMap may be the most useful, if the next step after flattening is mapping.

NOTE: Thanks @MartinR for the syntax tip.

Upvotes: 5

Martin R
Martin R

Reputation: 539965

Another possible solution is

[].join(numbers.values)

And if you want the values in the order corresponding to the sorted dictionary keys then it would be

flatMap(sorted(numbers.keys)) { numbers[$0]! }

Upvotes: 6

Ian
Ian

Reputation: 12768

With a combination of numbers.values.array and a reduce function you can simplify this down in one line of code.

numbers.values.array.reduce([], combine: +) // [5,6,7,2,3,9]

However, I would like to note that since you are using a dictionary, you cannot guarantee that the values will be sorted, so you can use the sorted function to accomplish this:

sorted(numbers.values.array.reduce([], combine: +), <) // [2,3,5,6,7,9]

As @Jeffery Thomas stated, you can also use flatmap which was just added in Swift 1.2:

sorted(numbers.values.array.flatMap { $0 }, <)

And to take it a step further, using the global sorted function, the < is extraneous because it is the default and using the global reduce and flatMap functions, you can remove the array property as pointed out by Martin R, so it can be reduced down to:

sorted(reduce(numbers.values, [], +))
sorted(flatMap(numbers.values) { $0 })

Upvotes: 7

Related Questions