如何使用高阶函数获得对角线的总和?

How to get the summation of diagonal lines using higher-order functions?

考虑以下二维数组:

let array = [
                [11, 2, 4],
                [4, 5, 6],
                [10, 8, -12]
            ]

我要得到的是对角线的求和:

我可以使用标准 for-in 循环实现它:

var firstDiagnal = 0
var secondDiagnal = 0

for i in 0..<array.count {
    firstDiagnal += array[i][i]
    secondDiagnal += array[i][array[i].count - 1 - i]
}

print(firstDiagnal)
print(secondDiagnal)

但是,如果我们尝试使用 高阶 函数会怎样?例如 mapreduce?

要获得第一个总和,您需要第 i 行的第 i 个元素:

let firstDiag = array.enumerated().map { [[=10=]] }.reduce(0, +)

要得到第二个总和,你想要同样的东西,但列颠倒了:

let secondDiag = array.enumerated().map { .reversed()[[=11=]] }.reduce(0, +)

首先,您可以编写一个简洁的扩展来从嵌套数组中获取对角线:

extension Array {

    func diagonal<T>(order: Int) -> [T] where Element == [T] {

        var order = order
        return self.compactMap {
            guard order >= 0, [=10=].count > order else {
                order -= 1
                return nil
            }
            let output = [=10=][order]
            order -= 1
            return output
        }
    }
}

let array = [[1, 2, 3],
             [4, 5, 6],
             [7, 8, 9]]

print(array.diagonal(order: 0)) // [1]
print(array.diagonal(order: 1)) // [2, 4]
print(array.diagonal(order: 2)) // [3, 5 ,7]
print(array.diagonal(order: 3)) // [6, 8]

这只是沼泽标准归约和求和的一个简单例子:

let fristDiagonal = array.diagonal(order: 0).reduce(0, +)
let secondDiagonal = array.diagonal(order: 1).reduce(0, +)