Smooth an array of arrays in Swift

Is there a copy in Swift to flatten in Scala, Xtend, Groovy, Ruby and co?

 var aofa = [[1,2,3],[4],[5,6,7,8,9]] aofa.flatten() // shall deliver [1,2,3,4,5,6,7,8,9] 

Of course, I could use a shorthand for this, but this kind of sucks

 var flattened = aofa.reduce(Int[]()){ a,i in var b : Int[] = a b.extend(i) return b } 
+86
swift
Jun 28 '14 at 9:03
source share
10 answers

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()) 
+297
Sep 25 '14 at 15:07
source share

In the Swift standard library, the joined function is implemented for all types that comply with the 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 some cases, using joined() can be useful because it returns a lazy collection instead of a new array, but can always be converted to an array when passed to Array() initializer, as in the example above.

+25
01 Oct '15 at 13:11
source share

Swift 4.x

To add a bit more flatMap to the array, if there is an array containing an array of arrays, then flatMap not actually work.

Assume an array

 var array:[Any] = [1,2,[[3,4],[5,6,[7]]],8] 

Which returns flatMap or compactMap :

 array.compactMap({$0}) //Output [1, 2, [[3, 4], [5, 6, [7]]], 8] 

To solve this problem, we can use our simple looping 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) 

Result:

 [1, 2, 3, 4, 5, 6, 7, 8] 

This function will help smooth any array, given the case of Int here

Exit on the playground: enter image description here

+5
Jul 23 '18 at 12:22
source share

This worked for me:

 let numbers = [[1, 2, 3], [4, 5, 6]] let flattenNumbers = numbers.reduce([], combine: +) 
+3
Jan 12 '15 at 20:22
source share

Another common implementation of reduce ,

 let numbers = [[1,2,3],[4],[5,6,7,8,9]] let reduced = reduce(numbers,[],+) 

This does the same, but can provide more information about what happens in reduce .

From Apple docs

 func reduce<S : SequenceType, U>(sequence: S, initial: U, combine: (U, S.Generator.Element) -> U) -> U 

Description

Returns the result of a repeated call of the union with the accumulated value, initialized by the initial and each element of the sequence, in turn.

+2
Oct 11 '14 at 5:30
source share

Swift 4.x

This use of flatMap not deprecated, and it does for that. https://developer.apple.com/documentation/swift/sequence/2905332-flatmap

 var aofa = [[1,2,3],[4],[5,6,7,8,9]] aofa.flatMap { $0 } //[1,2,3,4,5,6,7,8,9] 
+1
Jan 03 '19 at 14:59
source share

You can smooth the nested array using the following method:

 var arrays = [1, 2, 3, 4, 5, [12, 22, 32], [[1, 2, 3], 1, 3, 4, [[[777, 888, 8999]]]]] as [Any] func flatten(_ array: [Any]) -> [Any] { return array.reduce([Any]()) { result, current in switch current { case(let arrayOfAny as [Any]): return result + flatten(arrayOfAny) default: return result + [current] } } } let result = flatten(arrays) print(result) /// [1, 2, 3, 4, 5, 12, 22, 32, 1, 2, 3, 1, 3, 4, 777, 888, 8999] 
0
Jan 21 '19 at 9:33
source share

Swift 4.2

I wrote a simple array extension below. You can use to smooth an array that contains another array or element. unlike the join () method.

 public extension Array { public func flatten() -> [Element] { return Array.flatten(0, self) } public static func flatten<Element>(_ index: Int, _ toFlat: [Element]) -> [Element] { guard index < toFlat.count else { return [] } var flatten: [Element] = [] if let itemArr = toFlat[index] as? [Element] { flatten = flatten + itemArr.flatten() } else { flatten.append(toFlat[index]) } return flatten + Array.flatten(index + 1, toFlat) } } 

using:

 let numbers: [Any] = [1, [2, "3"], 4, ["5", 6, 7], "8", [9, 10]] numbers.flatten() 
0
Jan 22 '19 at 12:07
source share
-one
Mar 24 '17 at 5:08
source share
 func convert(){ let arr = [[1,2,3],[4],[5,6,7,8,9]] print("Old Arr = ",arr) var newArr = [Int]() for i in arr{ for j in i{ newArr.append(j) } } print("New Arr = ",newArr) } 

enter image description here

-one
Mar 23 '18 at 12:06
source share



All Articles