我刚才问了一个类似的问题。它问我怎样才能像这样转换数组:
[[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 3的HLGridNode
(它基本上是一组网格状布局中的正方形)作为棋盘游戏的棋盘。要编辑网格节点的内容,我需要传入1D精灵节点数组,而不是2D数组。
为了让我的生活更轻松,我将模型对象存储在2D数组中。这样,我可以参考左边的sqaure 5个方块和顶部的2个方块:
modelObjects[5][2]
如果我使用.flatMap { $0 }
展平2D数组并将结果传递给网格节点,modelObjects[5][2]
似乎是左边2个正方形和顶部5个正方形。
这不是HLSpriteKit的重复,因为这个问题似乎有一定数量的数组可供使用。虽然我可以把我的2D数组放到一个循环中,并做那些enumerate().map {...}
的东西,但这似乎是一个非常冗长的方法。我认为使用2D数组必须更简单。
答案 0 :(得分:5)
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
}
}