通过混合 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"]