如何以这种方式展平阵列*迅速?

时间:2016-10-06 07:03:46

标签: swift multidimensional-array flatten

我刚才问了一个类似的问题。它问我怎样才能像这样转换数组:

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

到此:

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

但是现在我想将相同的数组转换为:

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

假设所有子阵列具有相同的长度。

如果您还没有注意到,结果中的前三项是三个子阵列中的第一项。结果中的第四,第五和第六项是每个子阵列的第二项。

如果您仍然不明白,也许这会有所帮助:

原始阵列:

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

结果:

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

目前,我有这个:

func flatten(array: [[Int]]) -> [Int] {
    var flat = [Int]()
    for i in 0..<array[0].count {
        for subarray in array {
            flat.append(subarray[i])
        }
    }
    return flat
}

我不认为这是非常不稳定的。我怎么能以一种很快的方式做到这一点?

为了避免成为XY问题,这就是我想要这样做的原因。

我正在开发一款棋盘游戏。我正在使用来自Richardson's Maturity Model level 3HLGridNode(它基本上是一组网格状布局中的正方形)作为棋盘游戏的棋盘。要编辑网格节点的内容,我需要传入1D精灵节点数组,而不是2D数组。

为了让我的生活更轻松,我将模型对象存储在2D数组中。这样,我可以参考左边的sqaure 5个方块和顶部的2个方块:

modelObjects[5][2]

如果我使用.flatMap { $0 }展平2D数组并将结果传递给网格节点,modelObjects[5][2]似乎是左边2个正方形和顶部5个正方形。

这不是HLSpriteKit的重复,因为这个问题似乎有一定数量的数组可供使用。虽然我可以把我的2D数组放到一个循环中,并做那些enumerate().map {...}的东西,但这似乎是一个非常冗长的方法。我认为使用2D数组必须更简单。

2 个答案:

答案 0 :(得分:5)

这是Shadow Of answer的改进:

extension Collection where Self.Iterator.Element: RandomAccessCollection { 
    func transposed() -> [[Self.Iterator.Element.Iterator.Element]] {
        guard let firstRow = self.first else { return [] }
        return firstRow.indices.map { index in
            self.map{ $0[index] }
        }
    }
}

let matrix = [
    [1, 2, 3, 4],
    [5, 6, 7, 8],
    [9, 10, 11, 12],
]
matrix.transposed().forEach{ print($0) }

答案 1 :(得分:1)

您可以通过转置2d矩阵来接收您想要的结果,例如,使用此函数:

Image.x = (Image.x * ScrollView.zoomScale) - ScrollView.contentOffset.x
Image.y = (Image.y * ScrollView.zoomScale) - ScrollView.contentOffset.y

然后应用func matrixTranspose<T>(_ matrix: [[T]]) -> [[T]] { if matrix.isEmpty {return matrix} var result = [[T]]() for index in 0..<matrix.first!.count { result.append(matrix.map{$0[index]}) } return result } flatten在swift 3中)。

joined

扩展版本:

let arr = [[1,2,3],[4,5,6],[7,8,9]]
print(matrixTranspose(arr))
// [[1, 4, 7], [2, 5, 8], [3, 6, 9]]

print(matrixTranspose(arr).flatMap{$0})
// [1, 4, 7, 2, 5, 8, 3, 6, 9]

使用

extension Collection where Self.Iterator.Element: Collection {
    var transpose: Array<Array<Self.Iterator.Element.Iterator.Element>> {
        var result = Array<Array<Self.Iterator.Element.Iterator.Element>>()
        if self.isEmpty {return result}

        var index = self.first!.startIndex
        while index != self.first!.endIndex {
            var subresult = Array<Self.Iterator.Element.Iterator.Element>()
            for subarray in self {
                subresult.append(subarray[index])
            }
            result.append(subresult)
            index = self.first!.index(after: index)
        }
        return result
    }
}