Arrays 如何在二维数组范围内使用flatMap()和reduce()

Arrays 如何在二维数组范围内使用flatMap()和reduce(),arrays,swift,matrix,multidimensional-array,flatten,Arrays,Swift,Matrix,Multidimensional Array,Flatten,我有一个二维数组,我想使用类似于平面图的东西,并将二维数组的范围缩小。在我的示例中,我想将每行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).for

我有一个二维数组,我想使用类似于平面图的东西,并将二维数组的范围缩小。在我的示例中,我想将每行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[$0][col-1...col+1].compactMap { $0 }.reduce(reducedValue, +)
}
预期产出为:

51
//6 + 8 + 4 + 7 + 4 + 6 + 4 + 5 + 7
不过,我想知道是否有类似于此的解决方案:

reducedValue = array[row-1...row+1][col-1...col+1].compactMap { $0 }.reduce(0, +)
或者,即使没有类似的compactMap:

reducedValue = array[row-1...row+1][col-1...col+1].reduce(0, +)

您可以展平数组,然后
减少该数组。例如:

let total = array[row-1...row+1]
    .flatMap { $0[col-1...col+1] }
    .reduce(0, +)
这将产生:

五十一


如果希望避免构建扁平阵列的开销(除非处理非常大的子阵列,即数百万个值,否则这是无关紧要的),则可以延迟执行计算:

let total = array[row-1...row+1]
    .lazy
    .flatMap { $0[col-1...col+1] }
    .reduce(0, +)

另一个选项,用于添加选定行和列的值,而不创建中间数组:

let value = array[row-1...row+1].reduce(0, { $0 + $1[col-1...col+1].reduce(0, +) })
print(value) // 51

外部的
reduce()
迭代选定的行,并为每一行添加选定列中的值的总和,这些值在内部的
reduce()
中计算,而函数方法将为您提供最简洁的代码

let result=array[row-1…row+1]。reduce(到:0){$0+=$1[col-1…col+1]。reduce(到:0,+=)}
,不应忽略经典的命令式代码:

var result = 0
for i in row-1...row+1 {
    for j in col-1...col+1 {
        result += array[i][j]
    }
}

命令式方法虽然更加详细,而且不是100%快速的惯用方法(当存在
let
替代方案时,使用
var
),但在处理数学概念的特定上下文中更具可读性。

请给出输入(您有)和所需输出。我更新了我的问题。谢谢!:)就理解性和可读性而言,我也喜欢命令式代码。然而,我的原始代码已经嵌入到两个类似的for-in循环中,用于在2d数组上迭代。并将每个值存储在新的二维数组中。这将意味着4个级别的for in循环。:)@MarcoBoerner,是的,4级for循环一点也不好。您可能希望将该逻辑分成两部分:计算2d数组,计算每个2d数组的和,而不管您采用的和计算方法(函数式或命令式)