如何在二维数组的范围内使用 flatMap() 和 reduce()
How to use flatMap() and reduce() on a range of a 2d array
我有一个二维数组,我想使用类似于 flatMap 的东西,并与每个二维的范围一起减少。在我的示例中,我想在每行 0 到 2 中添加从位置 1 到 3 的每个数字。
目前我的代码看起来类似于以下内容并且确实有效。
let array = [
[3,6,8,4],
[3,7,4,6],
[2,4,5,7],
[5,3,7,4]
]
let row = 1
let col = 2
var reducedValue = 0
(row-1...row+1).forEach {
reducedValue = array[[=10=]][col-1...col+1].compactMap { [=10=] }.reduce(reducedValue, +)
}
预期输出为:
51
//6 + 8 + 4 + 7 + 4 + 6 + 4 + 5 + 7
但是我想知道是否有类似于这个的解决方案:
reducedValue = array[row-1...row+1][col-1...col+1].compactMap { [=12=] }.reduce(0, +)
或者甚至没有类似这样的 compactMap:
reducedValue = array[row-1...row+1][col-1...col+1].reduce(0, +)
您可以将数组的数组展平,然后 reduce
。例如:
let total = array[row-1...row+1]
.flatMap { [=10=][col-1...col+1] }
.reduce(0, +)
产生:
51
如果您想避免构建扁平化数组的开销(这无关紧要,除非处理非常大的子数组,即数百万个值),您可以延迟执行计算:
let total = array[row-1...row+1]
.lazy
.flatMap { [=11=][col-1...col+1] }
.reduce(0, +)
另一个选项,它添加所选行和列的值而不创建中间数组:
let value = array[row-1...row+1].reduce(0, { [=10=] + [col-1...col+1].reduce(0, +) })
print(value) // 51
外部 reduce()
遍历选定的行并为每一行添加选定列中的值的总和,这些值是在内部 reduce()
.[=13 中计算的=]
虽然函数式方法会给您最简洁的代码
let result = array[row-1...row+1].reduce(into: 0) { [=10=] += [col-1...col+1].reduce(into: 0, +=) }
,经典的命令式代码不容忽视:
var result = 0
for i in row-1...row+1 {
for j in col-1...col+1 {
result += array[i][j]
}
}
命令式方法虽然更冗长而且不是 100% Swift 惯用语(当 let
替代存在时使用 var
),但在这个特定的上下文中更具可读性,处理数学概念。
我有一个二维数组,我想使用类似于 flatMap 的东西,并与每个二维的范围一起减少。在我的示例中,我想在每行 0 到 2 中添加从位置 1 到 3 的每个数字。
目前我的代码看起来类似于以下内容并且确实有效。
let array = [
[3,6,8,4],
[3,7,4,6],
[2,4,5,7],
[5,3,7,4]
]
let row = 1
let col = 2
var reducedValue = 0
(row-1...row+1).forEach {
reducedValue = array[[=10=]][col-1...col+1].compactMap { [=10=] }.reduce(reducedValue, +)
}
预期输出为:
51
//6 + 8 + 4 + 7 + 4 + 6 + 4 + 5 + 7
但是我想知道是否有类似于这个的解决方案:
reducedValue = array[row-1...row+1][col-1...col+1].compactMap { [=12=] }.reduce(0, +)
或者甚至没有类似这样的 compactMap:
reducedValue = array[row-1...row+1][col-1...col+1].reduce(0, +)
您可以将数组的数组展平,然后 reduce
。例如:
let total = array[row-1...row+1]
.flatMap { [=10=][col-1...col+1] }
.reduce(0, +)
产生:
51
如果您想避免构建扁平化数组的开销(这无关紧要,除非处理非常大的子数组,即数百万个值),您可以延迟执行计算:
let total = array[row-1...row+1]
.lazy
.flatMap { [=11=][col-1...col+1] }
.reduce(0, +)
另一个选项,它添加所选行和列的值而不创建中间数组:
let value = array[row-1...row+1].reduce(0, { [=10=] + [col-1...col+1].reduce(0, +) })
print(value) // 51
外部 reduce()
遍历选定的行并为每一行添加选定列中的值的总和,这些值是在内部 reduce()
.[=13 中计算的=]
虽然函数式方法会给您最简洁的代码
let result = array[row-1...row+1].reduce(into: 0) { [=10=] += [col-1...col+1].reduce(into: 0, +=) }
,经典的命令式代码不容忽视:
var result = 0
for i in row-1...row+1 {
for j in col-1...col+1 {
result += array[i][j]
}
}
命令式方法虽然更冗长而且不是 100% Swift 惯用语(当 let
替代存在时使用 var
),但在这个特定的上下文中更具可读性,处理数学概念。