How to transpose an array more Swiftly?

后端 未结 2 1829
被撕碎了的回忆
被撕碎了的回忆 2020-12-19 11:35

I asked a similar question a while ago. It was asking how can I turn an array like this:

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

to this:



        
相关标签:
2条回答
  • 2020-12-19 12:16

    Here's an improvement on Shadow Of's answer:

    extension Collection where Self.Iterator.Element: RandomAccessCollection {
        // PRECONDITION: `self` must be rectangular, i.e. every row has equal size.
        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) }
    
    0 讨论(0)
  • 2020-12-19 12:25

    You can receive result you wanted by transpose your 2d matrix, using, for example, this function:

    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
    }
    

    and applying flatten (joined in swift 3) then.

    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 version:

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

    with usage

    let arr = [[1,2,3],[4,5,6],[7,8,9]]
    print(arr.transpose)
    // [[1, 4, 7], [2, 5, 8], [3, 6, 9]]
    
    0 讨论(0)
提交回复
热议问题