有没有办法在 Swift 中中断数组的 reduce 函数?
Is there a way to break from an array's reduce function in Swift?
有没有一种方法可以在 for
循环中但在数组的 reduce()
函数中执行类似于 break
的操作?
例如考虑我有一个数组:
var flags = [false, false, true, false, false, true, false]
...我需要对它们进行累积 ||
。使用 for
循环,以下是可能的:
var resultByFor = false
for flag in flags {
if flag {
resultByFor = true
break
}
}
...也就是说,在我们得到第一个 true
的那一刻,没有必要完成循环,因为无论如何结果都是 true
。
加上reduce()
,下面看起来还挺整洁的:
var resultByReduce = flags.reduce(false) { [=13=] || }
然而,对于示例中给出的数组,for
循环体将仅执行 3 次,而 reduce()
函数闭包将被触发完整 7 次。
有没有办法让 reduce()
在第 3 次迭代中也能退出(就像在 for
循环中一样)?
[更新]
我把问题简单化了。原来的问题更像这样:
extension Int {
func isWholeMultiplesOf(base: Int) -> Bool {
return (self % base) == 0
}
}
var numbers = [3, 5, 6, 7, 2, 3, 8]
var resultByFor = false
// The loop body will be triggered only 3 times
for number in numbers {
if number.isWholeMultiplesOf(2) {
resultByFor = true
break
}
}
// The closure of reduce() will be triggered 7 times
var resultByReduce = numbers.reduce(false) {
[=14=] || .isWholeMultiplesOf(2)
}
...即我有一个对象数组,我想知道是否至少有一个对象具有某种评估方法 true
.
正如其他人所建议的,您可以使用 contains
来达到此目的:
var flags = [false, false, true, false, false, true, false]
contains(flags, true) //--> true
另一种选择是使用 find
搜索您要查找的第一个实例,在本例中为 true
:
var flags = [false, false, true, false, false, true, false]
find(flags, true) // --> 2, returns nil if not found
let containsTrue = (find(flags, true) != nil)
编辑:Swift 的较新版本在相关收集协议上公开这些函数而不是全局函数。
var flags = [false, false, true, false, false, true, false]
flags.contains(where: { [=12=] == true })
flags.contains(true) // if checking for a specific element
let index = flags.firstIndex(where: ${ [=12=] == true }) // --> 2
它在 Swift 标准库中不可用,但您可以制作它。在 my blog post 中,我描述了我提出的解决方案。在你的情况下,它在呼叫方看起来像这样:
flags.reduce(false, { [=10=] || }, until: { [=10=] })
您可以在 that Playground
中尝试一下
解决“原始问题”的现代方法是
[3, 5, 6, 7, 2, 3, 8].contains {
[=10=].isMultiple(of: 2)
}
迭代闭包没有break
,就像函数主体中不允许break
一样。要模仿它,你需要抛出一个错误。
for number in numbers {
guard !number.isMultiple(of: 2) else {
break
}
print(number)
}
try? numbers.forEach {
guard ![=12=].isMultiple(of: 2) else {
struct Error: Swift.Error { }
throw Error()
}
print([=12=])
}
有没有一种方法可以在 for
循环中但在数组的 reduce()
函数中执行类似于 break
的操作?
例如考虑我有一个数组:
var flags = [false, false, true, false, false, true, false]
...我需要对它们进行累积 ||
。使用 for
循环,以下是可能的:
var resultByFor = false
for flag in flags {
if flag {
resultByFor = true
break
}
}
...也就是说,在我们得到第一个 true
的那一刻,没有必要完成循环,因为无论如何结果都是 true
。
加上reduce()
,下面看起来还挺整洁的:
var resultByReduce = flags.reduce(false) { [=13=] || }
然而,对于示例中给出的数组,for
循环体将仅执行 3 次,而 reduce()
函数闭包将被触发完整 7 次。
有没有办法让 reduce()
在第 3 次迭代中也能退出(就像在 for
循环中一样)?
[更新]
我把问题简单化了。原来的问题更像这样:
extension Int {
func isWholeMultiplesOf(base: Int) -> Bool {
return (self % base) == 0
}
}
var numbers = [3, 5, 6, 7, 2, 3, 8]
var resultByFor = false
// The loop body will be triggered only 3 times
for number in numbers {
if number.isWholeMultiplesOf(2) {
resultByFor = true
break
}
}
// The closure of reduce() will be triggered 7 times
var resultByReduce = numbers.reduce(false) {
[=14=] || .isWholeMultiplesOf(2)
}
...即我有一个对象数组,我想知道是否至少有一个对象具有某种评估方法 true
.
正如其他人所建议的,您可以使用 contains
来达到此目的:
var flags = [false, false, true, false, false, true, false]
contains(flags, true) //--> true
另一种选择是使用 find
搜索您要查找的第一个实例,在本例中为 true
:
var flags = [false, false, true, false, false, true, false]
find(flags, true) // --> 2, returns nil if not found
let containsTrue = (find(flags, true) != nil)
编辑:Swift 的较新版本在相关收集协议上公开这些函数而不是全局函数。
var flags = [false, false, true, false, false, true, false]
flags.contains(where: { [=12=] == true })
flags.contains(true) // if checking for a specific element
let index = flags.firstIndex(where: ${ [=12=] == true }) // --> 2
它在 Swift 标准库中不可用,但您可以制作它。在 my blog post 中,我描述了我提出的解决方案。在你的情况下,它在呼叫方看起来像这样:
flags.reduce(false, { [=10=] || }, until: { [=10=] })
您可以在 that Playground
中尝试一下解决“原始问题”的现代方法是
[3, 5, 6, 7, 2, 3, 8].contains {
[=10=].isMultiple(of: 2)
}
迭代闭包没有break
,就像函数主体中不允许break
一样。要模仿它,你需要抛出一个错误。
for number in numbers {
guard !number.isMultiple(of: 2) else {
break
}
print(number)
}
try? numbers.forEach {
guard ![=12=].isMultiple(of: 2) else {
struct Error: Swift.Error { }
throw Error()
}
print([=12=])
}