代码之家  ›  专栏  ›  技术社区  ›  codingBoy

如何在Swift中优雅地转置2D数组[复制]

  •  0
  • codingBoy  · 技术社区  · 7 年前

    我刚才问了一个类似的问题。它在问我怎样才能变成这样的阵列:

    [[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问题,我想这样做的原因如下。

    我正在开发一个棋盘游戏。我在用 HLGridNode HLSpriteKit 作为棋盘游戏的棋盘。要编辑网格节点的内容,我需要传入一个由sprite节点组成的1D数组,而不是2D数组。

    为了使我的生活更简单,我将模型对象存储在一个二维数组中。这样,我就可以参考从左边起的5个正方形和从上面起的2个正方形:

    modelObjects[5][2]
    

    .flatMap { $0 } 并将结果传递给网格节点, modelObjects[5][2] 从左边看是2个正方形,从上面看是5个正方形。

    这不是 this 因为这个问题似乎有一定数量的数组要处理。尽管我可以把我的二维数组放入一个循环中,然后 enumerate().map {...} 事情,这似乎是一个非常冗长的方法。我认为用二维数组来做这件事一定比较简单。

    0 回复  |  直到 6 年前
        1
  •  7
  •   Alexander    7 年前

    这里有一个改进 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) }
    
        2
  •  1
  •   Yury    9 年前

    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 ( joined 在斯威夫特3)那么。

    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
        }
    }
    

    使用

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