Following task - make flat array from nested array. Because there are could be any levels of nested array we use
recursive approach.
For example - given array [1, [2, [3, 4, 5]]]. We need to get this [1, 2, 3, 4, 5]
Standard Approach
Algorithm
- In for loop go through the array
- If element of array is int then add it to new array
- If element of array is array too then make recursive invoke of function and send this array
We use
Any type as type of input array because input array can hold as integers as array. They both are value types, so
Any is suitable for us in this function.
Let's get coding.
import UIKit
let array: [Any] = [1, 2, [3]]
func makeFlatArray(_ array: [Any]) -> [Int] {
var flatArray = [Int]()
for item in array {
if let item = item as? Int {
flatArray.append(item)
} else if let item = item as? [Any] {
let result = makeFlatArray(item)
flatArray += result
}
}
return flatArray
}
print(makeFlatArray([1, 2, 3]))
// [1, 2, 3]
print(makeFlatArray([1, [2, 3, 4]]))
// [1, 2, 3, 4]
print(makeFlatArray([1, [2, [3, 4]]]))
// [1, 2, 3, 4]
print(makeFlatArray([[1], [2, [3, 4, [5]]]]))
// [1, 2, 3, 4, 5]
Using Generics
What if we want to use this function with array of any type. We should use Generics:
func makeFlatArrayGeneric<T>(_ array: [Any]) -> [T] {
var flatArray = [T]()
for item in array {
if let item = item as? T {
flatArray.append(item)
} else if let item = item as? [Any] {
let result: [T] = makeFlatArrayGeneric(item)
flatArray += result
}
}
return flatArray
}
Now we can use this function with any kind of array. With integer array as previous
let array: [Any] = [1, 2, [3], [4, [5]]]
let items: [Int] = makeFlatArrayGeneric(array)
// [1, 2, 3, 4, 5]
And with array of strings
let array: [Any] = ["A", "BB", ["CCC"], ["DD", ["EE"]]]
let items: [String] = makeFlatArrayGeneric(array)
// ["A", "BB", "CCC", "DD", "EE"]
Make Extension for Array
What if we want this feature for any array as built in method. Let's create extension for Array Type. Here we use Swift method flatMap.
extension Array {
func makeFlat() -> [Element] {
let flatArray = self.flatMap { (element) -> [Element] in
if let array = element as? Array {
return array.makeFlat()
}
return [element]
}
return flatArray
}
}
Result of using array extension.
let array: [Any] = ["A", "BB", ["CCC"], ["DD", ["EE"]]]
print(array.makeFlat())
// ["A", "BB", "CCC", "DD", "EE"]