问题
Consider the following 2D array:
let array = [
[11, 2, 4],
[4, 5, 6],
[10, 8, -12]
]
What I want to get is the summation of the diagonals:
- As
firstDiagnal
: 11 + 5 + (-12) = 4 - As
secondDiagnal
: 4 + 5 + 10 = 19
I could achieve it using a standard for-in
loop:
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)
However, what could it be if we tried to use higher-order functions? such as map
and reduce
?
回答1:
To get the first sum, you want the i'th element of the i'th row:
let firstDiag = array.enumerated().map { $1[$0] }.reduce(0, +)
To get the second sum, you want the same thing, but the columns reversed:
let secondDiag = array.enumerated().map { $1.reversed()[$0] }.reduce(0, +)
回答2:
To begin with, you can write a neat extension to get the diagonal out of a nested array:
extension Array {
func diagonal<T>(order: Int) -> [T] where Element == [T] {
var order = order
return self.compactMap {
guard order >= 0, $0.count > order else {
order -= 1
return nil
}
let output = $0[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]
It's then just simply a case of the bog-standard reduce and sum:
let fristDiagonal = array.diagonal(order: 0).reduce(0, +)
let secondDiagonal = array.diagonal(order: 1).reduce(0, +)
来源:https://stackoverflow.com/questions/52646875/how-to-get-the-summation-of-diagonal-lines-using-higher-order-functions