Flatten an Array of Arrays in Swift
Swift >= 3.0
reduce
:
let numbers = [[1,2,3],[4],[5,6,7,8,9]]let reduced = numbers.reduce([], +)
flatMap
:
let numbers = [[1,2,3],[4],[5,6,7,8,9]]let flattened = numbers.flatMap { $0 }
joined
:
let numbers = [[1,2,3],[4],[5,6,7,8,9]]let joined = Array(numbers.joined())
In Swift standard library there is joined
function implemented for all types conforming to Sequence
protocol (or flatten
on SequenceType
before Swift 3), which includes Array
:
let numbers = [[1,2,3],[4],[5,6,7,8,9]]let flattened = Array(numbers.joined())
In certain cases use of joined()
can be beneficial as it returns a lazy collection instead of a new array, but can always be converted to an array when passed to Array()
initialiser like in the example above.
Swift 4.x/5.x
Just to add a bit more complexity in the array, if there is an array that contains array of arrays, then flatMap
will actually fail.
Suppose the array is
var array:[Any] = [1,2,[[3,4],[5,6,[7]]],8]
What flatMap
or compactMap
returns is:
array.compactMap({$0})//Output[1, 2, [[3, 4], [5, 6, [7]]], 8]
In order to solve this problem, we can use our simple for loop logic + recursion
func flattenedArray(array:[Any]) -> [Int] { var myArray = [Int]() for element in array { if let element = element as? Int { myArray.append(element) } if let element = element as? [Any] { let result = flattenedArray(array: element) for i in result { myArray.append(i) } } } return myArray}
So call this function with the given array
flattenedArray(array: array)
The Result is:
[1, 2, 3, 4, 5, 6, 7, 8]
This function will help to flatten any kind of array, considering the case of Int
here