使用 Reduce 求和 (Swift)

Using Reduce to sum (Swift)

我正在查看可以使用 reduce 对数组求和的示例,但主要是查找带有数字的示例。 您如何使用 reduce()Foo 中的所有 Bar 加起来,其中 isAvailable 设置为 true

你愿意像我那样写吗? (考虑到可读性和效率)

struct Foo {
    var isAvailable: Bool
    var bars: [Bar]
}

struct Bar {
    var name: String
}

let array = [
    Foo(isAvailable: true, bars: [ Bar(name: "Bill"), Bar(name: "Donald") ]),
    Foo(isAvailable: false, bars: [ Bar(name: "Barack"), Bar(name: "Joe") ]),
    Foo(isAvailable: true, bars: [ Bar(name: "George"), Bar(name: "Ronald") ])
]


// Do this with reduce??
var totalCount = 0
for foo in array where foo.isAvailable {
    totalCount += foo.bars.count
}
let sum = array
    .filter { [=10=].isAvailable }
    .map { [=10=].bars.count }
    .reduce(0, +)

您可以使用单个 reduce 操作实现此目的。从 0 结果开始,然后在闭包中,检查 foo.isAvailable 并且仅在 true.

时增加计数
let totalCount = array.reduce(0, { accumulatingResult, foo in
  guard foo.isAvailable else { return accumulatingResult }
  return accumulatingResult + foo.bars.count
})

简而言之:

let reduced = array.reduce(0) { .isAvailable ? [=10=] + .bars.count : [=10=] }

现在,让我们明确一下:

逻辑很简单:

  • 我们设置初始值为0
  • 在闭包中,我们有两个参数,第一个是当前值(开始时是初始值),我们将在每次迭代时递增,第二个是数组的元素。我们return然后我们根据你的情况增加或不增加的新值(部分)(这里是isAvailable

明确地:

let reduced2 = array.reduce(0) { partial, current in
    if current.isAvailable {
        return partial + current.bars.count
    } else {
        return partial
    }
}

用三元if:

let reduced3 = array.reduce(0) { partial, current in
    return current.isAvailable ? partial + current.bars.count : partial
}

删除 return,请参阅 Swift 的 Functions of Swift or Implicit Returns from Single-Expression Closures of Closures 中的 Functions With an Implicit Return

let reduced4 = array.reduce(0) { partial, current in
    current.isAvailable ? partial + current.bars.count : partial
}

在 Swift 的 ClosuresShorthand Argument Names

let reduced5 = array.reduce(0) { .isAvailable ? [=14=] + .bars.count : [=14=] }