Swift - 如何减少矩阵
Swift - how to reduce matrix
我有一个 3 维数组(array[x][y][z]
,x y z
可以灵活)
var array = [ [[1,1,1],[0,0,0],[1,1,1]],
[[1,0,1],[1,0,1],[1,0,1]],
[[1,1,1],[0,0,0],[1,1,1]]
]
如何将 3D 缩小为 2D 以:array[z][y]
[3,1,3],[2,0,2],[3,1,3]
我阅读了说明 但不知道如何应用到我的。
更新:
这是逻辑
鉴于此
let matrix = [
[[1,1,1],[0,0,0],[1,1,1]],
[[1,0,1],[1,0,1],[1,0,1]],
[[1,1,1],[0,0,0],[1,1,1]]
]
让我们计算这些
let all = matrix.joined().enumerated()
let a = all.filter { [=11=].offset % 3 == 0 }.map { [=11=].element[0] }.reduce(0, +)
let b = all.filter { [=11=].offset % 3 == 1 }.map { [=11=].element[0] }.reduce(0, +)
let c = all.filter { [=11=].offset % 3 == 2 }.map { [=11=].element[0] }.reduce(0, +)
let d = all.filter { [=11=].offset % 3 == 0 }.map { [=11=].element[1] }.reduce(0, +)
let e = all.filter { [=11=].offset % 3 == 1 }.map { [=11=].element[1] }.reduce(0, +)
let f = all.filter { [=11=].offset % 3 == 2 }.map { [=11=].element[1] }.reduce(0, +)
let g = all.filter { [=11=].offset % 3 == 0 }.map { [=11=].element[2] }.reduce(0, +)
let h = all.filter { [=11=].offset % 3 == 1 }.map { [=11=].element[2] }.reduce(0, +)
let i = all.filter { [=11=].offset % 3 == 2 }.map { [=11=].element[2] }.reduce(0, +)
最后让我们把这些值放在一起[=13=]
let res = [[a, b, c], [d, e, f], [g, h, i]]
因为听起来您正在寻找函数式编程的单行代码,所以这是您的答案:
array.indices.map{ j in array.indices.map{ i in array.map{ [=10=][i][j] }.reduce(0, +) } }
它与这段代码基本相同,虽然更长,但我认为它更容易阅读并且让我在推理时更少头疼。
func flatten2(_ array:[[[Int]]]) -> [[Int]]
{
var result:[[Int]] = []
for j in 0..<array.count
{
var row:[Int] = []
for i in 0..<array.count
{
row.append(array.map{ [=11=][i][j] }.reduce(0, +))
}
result.append(row)
}
return result
}
请记住,单行代码的编译时间要长两个数量级,因为 Swift 编译器对于函数式和闭包编程不是很优化,所以它必须构建巨大的重载树解析该表达式。因为我怀疑这是CS期末练习题,拜托,拜托,让你可怜的TA生活更轻松,使用多行。
让我们首先形成一个效用函数作为矩阵式数组的扩展("cw" 表示按列):
extension Array where Element == [[Int]] {
func cwsum(_ ix1:Int, _ ix2:Int) -> Int {
return reduce(0) {[=10=] + [ix1][ix2]}
}
}
那么如果数组是:
let array = [[[1,1,1],[0,0,0],[1,1,1]],
[[1,0,1],[1,0,1],[1,0,1]],
[[1,1,1],[0,0,0],[1,1,1]]]
...那么答案是:
[[array.cwsum(0,0), array.cwsum(1,0), array.cwsum(2,0)],
[array.cwsum(0,1), array.cwsum(1,1), array.cwsum(2,1)],
[array.cwsum(0,2), array.cwsum(1,2), array.cwsum(2,2)]]
// [[3, 1, 3], [2, 0, 2], [3, 1, 3]]
但是等等——我想我在这里看到了一个规律!我们可以重写它而无需对索引进行硬编码,如:
var result = [[Int]]()
for j in 0..<3 {
var r1 = [Int]()
for i in 0..<3 {
r1.append(array.cwsum(i,j))
}
result.append(r1)
} // result is now [[3, 1, 3], [2, 0, 2], [3, 1, 3]]
好的,但是在我们可以循环和 append
的地方,我们可以 map
代替,从而将 i
变成映射变量:
var result = [[Int]]()
for j in 0..<3 {
result.append((0..<3).map{i in array.cwsum(i,j)})
}
但是我们也可以为 j
这样做——因此它变成了一行:
result = (0..<3).map{j in (0..<3).map{i in array.cwsum(i,j)}}
经过几个小时的尝试。这是我的输出,它非常简单并且与 reduce
无关。 3d数组的输入是灵活的x,y,z
let x = array.count
let y = array[0].count
let z = array[0][0].count
var final = Array(repeating: Array(repeating: 0, count: y), count: z)
for i in 0..<z {
for ii in 0..<y {
var sum = 0
for iii in 0..<x {
sum = sum + array[iii][ii][i]
}
final[i][ii] = sum
}
}
我有一个 3 维数组(array[x][y][z]
,x y z
可以灵活)
var array = [ [[1,1,1],[0,0,0],[1,1,1]],
[[1,0,1],[1,0,1],[1,0,1]],
[[1,1,1],[0,0,0],[1,1,1]]
]
如何将 3D 缩小为 2D 以:array[z][y]
[3,1,3],[2,0,2],[3,1,3]
我阅读了说明
更新:
这是逻辑
鉴于此
let matrix = [
[[1,1,1],[0,0,0],[1,1,1]],
[[1,0,1],[1,0,1],[1,0,1]],
[[1,1,1],[0,0,0],[1,1,1]]
]
让我们计算这些
let all = matrix.joined().enumerated()
let a = all.filter { [=11=].offset % 3 == 0 }.map { [=11=].element[0] }.reduce(0, +)
let b = all.filter { [=11=].offset % 3 == 1 }.map { [=11=].element[0] }.reduce(0, +)
let c = all.filter { [=11=].offset % 3 == 2 }.map { [=11=].element[0] }.reduce(0, +)
let d = all.filter { [=11=].offset % 3 == 0 }.map { [=11=].element[1] }.reduce(0, +)
let e = all.filter { [=11=].offset % 3 == 1 }.map { [=11=].element[1] }.reduce(0, +)
let f = all.filter { [=11=].offset % 3 == 2 }.map { [=11=].element[1] }.reduce(0, +)
let g = all.filter { [=11=].offset % 3 == 0 }.map { [=11=].element[2] }.reduce(0, +)
let h = all.filter { [=11=].offset % 3 == 1 }.map { [=11=].element[2] }.reduce(0, +)
let i = all.filter { [=11=].offset % 3 == 2 }.map { [=11=].element[2] }.reduce(0, +)
最后让我们把这些值放在一起[=13=]
let res = [[a, b, c], [d, e, f], [g, h, i]]
因为听起来您正在寻找函数式编程的单行代码,所以这是您的答案:
array.indices.map{ j in array.indices.map{ i in array.map{ [=10=][i][j] }.reduce(0, +) } }
它与这段代码基本相同,虽然更长,但我认为它更容易阅读并且让我在推理时更少头疼。
func flatten2(_ array:[[[Int]]]) -> [[Int]]
{
var result:[[Int]] = []
for j in 0..<array.count
{
var row:[Int] = []
for i in 0..<array.count
{
row.append(array.map{ [=11=][i][j] }.reduce(0, +))
}
result.append(row)
}
return result
}
请记住,单行代码的编译时间要长两个数量级,因为 Swift 编译器对于函数式和闭包编程不是很优化,所以它必须构建巨大的重载树解析该表达式。因为我怀疑这是CS期末练习题,拜托,拜托,让你可怜的TA生活更轻松,使用多行。
让我们首先形成一个效用函数作为矩阵式数组的扩展("cw" 表示按列):
extension Array where Element == [[Int]] {
func cwsum(_ ix1:Int, _ ix2:Int) -> Int {
return reduce(0) {[=10=] + [ix1][ix2]}
}
}
那么如果数组是:
let array = [[[1,1,1],[0,0,0],[1,1,1]],
[[1,0,1],[1,0,1],[1,0,1]],
[[1,1,1],[0,0,0],[1,1,1]]]
...那么答案是:
[[array.cwsum(0,0), array.cwsum(1,0), array.cwsum(2,0)],
[array.cwsum(0,1), array.cwsum(1,1), array.cwsum(2,1)],
[array.cwsum(0,2), array.cwsum(1,2), array.cwsum(2,2)]]
// [[3, 1, 3], [2, 0, 2], [3, 1, 3]]
但是等等——我想我在这里看到了一个规律!我们可以重写它而无需对索引进行硬编码,如:
var result = [[Int]]()
for j in 0..<3 {
var r1 = [Int]()
for i in 0..<3 {
r1.append(array.cwsum(i,j))
}
result.append(r1)
} // result is now [[3, 1, 3], [2, 0, 2], [3, 1, 3]]
好的,但是在我们可以循环和 append
的地方,我们可以 map
代替,从而将 i
变成映射变量:
var result = [[Int]]()
for j in 0..<3 {
result.append((0..<3).map{i in array.cwsum(i,j)})
}
但是我们也可以为 j
这样做——因此它变成了一行:
result = (0..<3).map{j in (0..<3).map{i in array.cwsum(i,j)}}
经过几个小时的尝试。这是我的输出,它非常简单并且与 reduce
无关。 3d数组的输入是灵活的x,y,z
let x = array.count
let y = array[0].count
let z = array[0][0].count
var final = Array(repeating: Array(repeating: 0, count: y), count: z)
for i in 0..<z {
for ii in 0..<y {
var sum = 0
for iii in 0..<x {
sum = sum + array[iii][ii][i]
}
final[i][ii] = sum
}
}