我想将simd_float4x4
或simd_float3x3
矩阵展平为单个float数组。
对于常规数组,我会使用
let arr = [[1,2,3],[4,5,6],[7,8,9]]
print(arr.flatMap { $0 })
如何优雅地为simd_float4x4
或simd_float3x3
结构执行此操作?
我目前正在使用
extension simd_float3x3 {
var array: [Float] {
return [columns.0.x, columns.0.y, columns.0.z,
columns.1.x, columns.1.y, columns.1.z,
columns.2.x, columns.2.y, columns.2.z]
}
}
let arr = simd_float3x3.init()
print(arr.array.compactMap({$0}))
答案 0 :(得分:1)
好吧,看来向量float3
和float4
已经实现了map
(通过实现Sequence
/ Collection
协议)。
所以我们唯一要做的就是为矩阵实现Collection
:
extension simd_float3x3: Collection {
public var startIndex: Int {
return 0
}
public var endIndex: Int {
return 3 // for `sims_float4x4` it would be 4, number of columns
}
public func index(after i: Int) -> Int {
return i + 1
}
}
现在我们可以这样做:
let matrix: simd_float3x3 = initCodeForTheMatrix()
matrix.flatMap { $0 }
您可以声明此方便的子协议,以避免为所有矩阵类型键入相同的startIndex
和index(after:)
:
public protocol SIMDCollection: Collection {}
extension SIMDCollection {
public var startIndex: Int {
return 0
}
public func index(after i: Int) -> Int {
return i + 1
}
}
// And use it like this:
extension simd_float3x3: SIMDCollection {
public var endIndex: Int {
return 3
}
}
extension simd_float4x4: SIMDCollection {
public var endIndex: Int {
return 4
}
}
extension simd_float3x2: SIMDCollection {
public var endIndex: Int {
return 3
}
}
// etc
它甚至可以走得更远,因为endIndex
对于具有相同simd_floatX_Y
和任何X
的所有Y
都是相同的。甚至是*float*
或*double*
还是什么都没关系。
答案 1 :(得分:0)
优雅的眼神在情人眼中。到目前为止,我已经提出了这个建议:
let s = simd_float3x3(simd_float3(1, 2, 3), simd_float3(4, 5, 6), simd_float3(7, 8, 9))
let y = (0..<3).flatMap { x in (0..<3).map { y in s[x][y] } }
print(y)
[1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0]