通过混合 Swift 中的元素将多个数组合并为一个?
Merge multiple arrays into one by mixing elements in Swift?
示例:
let a = [a1, a2, a3]
let b = [b1, b2]
let c = [c1, c2, c3, c4]
我需要以下结果:
[a1, b1, c1, a2, b2, c2, a3, c3, c4]
a1, b1, ... - 任何相同类型的对象
我目前的解决方案是创建这些数组的可变副本,并按指定顺序对每个数组依次调用 popFirst
,直到所有数组都变空。
但是是否可以通过使用内部 Swift 特征而不手动迭代来解决这个任务?例如像下面的代码:
[a, b, c].map { ... }.filter { ... }.reduce ...
试试这个 -
let a = ["a1", "a2", "a3"]
let b = ["b1", "b2"]
let c = ["c1", "c2", "c3", "c4"]
var d: [String] = []
let count = max(a.count, b.count, c.count)
for i in 0..<count {
if i < a.count { d.append(a[i]) }
if i < b.count { d.append(b[i]) }
if i < c.count { d.append(c[i]) }
}
print(d)
输出-
["a1", "b1", "c1", "a2", "b2", "c2", "a3", "c3", "c4"]
你可以这样做
let a = ["a1", "a2", "a3"]
let b = ["b1", "b2"]
let c = ["c1", "c2", "c3", "c4"]
let initArr = [a,b,c]
let maxCount = initArr.max(by: {[=10=].count < .count})?.count ?? 0
let newArr: [String] = (0..<maxCount).flatMap { (index) -> [String]in
var arr: [String] = []
_ = initArr.indices.map { (number)in
if index < initArr[number].count {
arr.append(initArr[number][index])
}
}
return arr
}
print(newArr) // ["a1", "b1", "c1", "a2", "b2", "c2", "a3", "c3", "c4"]
将此视为“转置”二维数组 [a, b, c]
,除非没有元素,否则您只需忽略它并继续前进。这让我想起了 ,只是你希望内部数组具有不同的大小。
我们可以通过找到具有最大 count
的内部数组来修改 Alexander 的答案以满足您的需要,并使用它而不是第一个内部数组。我们还将外部 map
更改为 flatMap
,因为您希望它变平。
我们还引入了一个safe:
下标,这样compactMap
就可以用来忽略那些“缺失”的元素。
extension Collection where Self.Element: RandomAccessCollection {
func transposed() -> [Self.Element.Element] {
guard let rowWithMaxElems = self.max(by: { [=10=].count < .count }) else { return [] }
return rowWithMaxElems.indices.flatMap { index in
self.compactMap { [=10=][safe: index] }
}
}
}
extension RandomAccessCollection {
subscript(safe index: Index) -> Element? {
get {
indices.contains(index) ? self[index] : nil
}
}
}
let a = [1, 2, 3]
let b = [4, 5]
let c = [6, 7, 8, 9]
let result = [a, b, c].transposed()
print(result)
这是一个使用基本 for
循环的解决方案,但它在您可以合并的数组数量方面很灵活
func merge<T>(_ arrays: [T]...) -> [T] {
guard let longest = arrays.max(by: { [=10=].count < .count })?.count else { return [] }
var result = [T]()
for index in 0..<longest {
for array in arrays {
guard index < array.count else { continue }
result.append(array[index])
}
}
return result
}
问题示例
print(merge(a, b, c))
["a1", "b1", "c1", "a2", "b2", "c2", "a3", "c3", "c4"]
示例:
let a = [a1, a2, a3]
let b = [b1, b2]
let c = [c1, c2, c3, c4]
我需要以下结果:
[a1, b1, c1, a2, b2, c2, a3, c3, c4]
a1, b1, ... - 任何相同类型的对象
我目前的解决方案是创建这些数组的可变副本,并按指定顺序对每个数组依次调用 popFirst
,直到所有数组都变空。
但是是否可以通过使用内部 Swift 特征而不手动迭代来解决这个任务?例如像下面的代码:
[a, b, c].map { ... }.filter { ... }.reduce ...
试试这个 -
let a = ["a1", "a2", "a3"]
let b = ["b1", "b2"]
let c = ["c1", "c2", "c3", "c4"]
var d: [String] = []
let count = max(a.count, b.count, c.count)
for i in 0..<count {
if i < a.count { d.append(a[i]) }
if i < b.count { d.append(b[i]) }
if i < c.count { d.append(c[i]) }
}
print(d)
输出-
["a1", "b1", "c1", "a2", "b2", "c2", "a3", "c3", "c4"]
你可以这样做
let a = ["a1", "a2", "a3"]
let b = ["b1", "b2"]
let c = ["c1", "c2", "c3", "c4"]
let initArr = [a,b,c]
let maxCount = initArr.max(by: {[=10=].count < .count})?.count ?? 0
let newArr: [String] = (0..<maxCount).flatMap { (index) -> [String]in
var arr: [String] = []
_ = initArr.indices.map { (number)in
if index < initArr[number].count {
arr.append(initArr[number][index])
}
}
return arr
}
print(newArr) // ["a1", "b1", "c1", "a2", "b2", "c2", "a3", "c3", "c4"]
将此视为“转置”二维数组 [a, b, c]
,除非没有元素,否则您只需忽略它并继续前进。这让我想起了
我们可以通过找到具有最大 count
的内部数组来修改 Alexander 的答案以满足您的需要,并使用它而不是第一个内部数组。我们还将外部 map
更改为 flatMap
,因为您希望它变平。
我们还引入了一个safe:
下标,这样compactMap
就可以用来忽略那些“缺失”的元素。
extension Collection where Self.Element: RandomAccessCollection {
func transposed() -> [Self.Element.Element] {
guard let rowWithMaxElems = self.max(by: { [=10=].count < .count }) else { return [] }
return rowWithMaxElems.indices.flatMap { index in
self.compactMap { [=10=][safe: index] }
}
}
}
extension RandomAccessCollection {
subscript(safe index: Index) -> Element? {
get {
indices.contains(index) ? self[index] : nil
}
}
}
let a = [1, 2, 3]
let b = [4, 5]
let c = [6, 7, 8, 9]
let result = [a, b, c].transposed()
print(result)
这是一个使用基本 for
循环的解决方案,但它在您可以合并的数组数量方面很灵活
func merge<T>(_ arrays: [T]...) -> [T] {
guard let longest = arrays.max(by: { [=10=].count < .count })?.count else { return [] }
var result = [T]()
for index in 0..<longest {
for array in arrays {
guard index < array.count else { continue }
result.append(array[index])
}
}
return result
}
问题示例
print(merge(a, b, c))
["a1", "b1", "c1", "a2", "b2", "c2", "a3", "c3", "c4"]