'Merge several arrays into one array
How can I merge several arrays into one 2D array?
Given I have the following input:
var arr1 = ["1", "2", "3"]
var arr2 = ["a", "b", "c"]
var arr3 = ["aa", "bb", "cc"]
, I need to have the output like this:
[["1", "a", "aa"], ["2", "b", "bb"], ["1", "c", "cc"]]
Solution 1:[1]
I think what you want is to combine the three arrays into a 2D array, and then transpose it.
To transpose a 2D array, you can find many solutions in this question.
This uses Crashalot's solution in the comments:
fileprivate func transpose<T>(input: [[T]]) -> [[T]] {
if input.isEmpty { return [[T]]() }
let count = input[0].count
var out = [[T]](repeating: [T](), count: count)
for outer in input {
for (index, inner) in outer.enumerated() {
out[index].append(inner)
}
}
return out
}
var arr1 = ["1", "2", "3"]
var arr2 = ["a", "b", "c"]
var arr3 = ["aa", "bb", "cc"]
transpose(input: [arr1, arr2, arr3])
If you want a more swifty transpose, you can use this (modified from here):
extension Collection where Self.Element: RandomAccessCollection {
func transposed() -> [[Self.Iterator.Element.Iterator.Element]]? {
guard Set(self.map { $0.count }).count == 1 else { return nil }
guard let firstRow = self.first else { return [] }
return firstRow.indices.map { index in
self.map{ $0[index] }
}
}
}
Solution 2:[2]
This is a naive expressive way, if you like.
[arr1,arr2,arr3].reduce([[],[],[]]) { result, next -> [[String]] in
return (0..<(next.count)).map{
var array = Array.init(result[$0])
array.append(next[$0]);
return array
}
}
or more directly:
[arr1,arr2,arr3].reduce(into: [[],[],[]]) { ( result : inout [[String]], next) in
_ = (0..<(next.count)).map{ result[$0].append(next[$0]);}
}
Solution 3:[3]
A variadic, FP-style, solution, that can pack an arbitrary number of arrays:
func pack<T>(_ arrays: [T]...) -> [[T]] {
guard !arrays.isEmpty else { return [] }
let minCount = arrays.map(\.count).min()!
return (0..<minCount).map { i in arrays.map { $0[i] } }
}
Usage:
let arr1 = ["1", "2", "3"]
let arr2 = ["a", "b", "c"]
let arr3 = ["aa", "bb", "cc"]
let result = pack(arr1, arr2, arr3)
// [["1", "a", "aa"], ["2", "b", "bb"], ["1", "c", "cc"]]
let anotherResult = pack(["firstName", "lastName"], ["John", "Doe"])
// [["firstName", "John"], ["lastName", "Doe"]]
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | |
| Solution 3 | Cristik |
