Is there a way to do something similar to break
from a for
loop but in array's reduce()
function?
是否有一种方法可以在数组的reduce()函数中执行类似于从for循环中中断的操作?
E.g. consider I have an array:
例如,假设我有一个数组:
var flags = [false, false, true, false, false, true, false]
... and I need to get a cumulative ||
on them. With a for
loop, the following would be possible:
…我需要得到累积的||。有了for循环,以下是可能的:
var resultByFor = false
for flag in flags {
if flag {
resultByFor = true
break
}
}
... i.e. at the moment we get our first true
there is no need to finish the loop as the result will be true
anyway.
…也就是说,当我们得到第一个真值时,不需要完成循环,因为结果无论如何都是真的。
With reduce()
, the following looks quite neat and tidy:
有了reduce(),下面看起来很整洁:
var resultByReduce = flags.reduce(false) { $0 || $1 }
However, with the array given in the example, the for
loop body would be executed only 3 times, while reduce()
function closure would get triggered full 7 times.
但是,对于示例中给出的数组,for循环主体只执行3次,而reduce()函数闭包将被触发7次。
Is there a way to make reduce()
to bail out on 3rd iteration as well (just like it can be done in for
loop)?
有没有一种方法可以让reduce()在第3次迭代中退出(就像它可以在for循环中完成一样)?
[UPD]
(乌利希期刊指南)
I oversimplified the question. The original problem was more like this:
我过于简单化的问题。最初的问题更像这样:
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) {
$0 || $1.isWholeMultiplesOf(2)
}
... i.e. I have an array of objects and I want to know if there is at least one of them that has certain method evaluating to true
.
…也就是说,我有一个对象数组,我想知道它们中是否至少有一个具有一定的值为true的方法。
3 个解决方案
#1
6
As others have suggested, you can use contains
for this purpose:
正如其他人所建议的,您可以为此目的使用contains:
var flags = [false, false, true, false, false, true, false]
contains(flags,true) //--> true
Another option is to use find
to search for the first instance of what you're looking for, in this case true
:
另一种选择是使用find来搜索您要查找的第一个实例,在本例中为真:
var flags = [false, false, true, false, false, true, false]
find(flags,true) // --> 2, returns nil if not found
let containsTrue = (find(flags,true) != nil)
#2
2
It's not available out of the box in the Swift Standard Library, but you can make it. In my blog post I have described my proposed solution. In your case it'll look like this on the call side:
在Swift标准库中,它是不可用的,但是您可以使用它。在我的博客中,我描述了我提出的解决方案。在你的情况下,在调用端看起来是这样的:
flags.reduce(false, { $0 || $1 }, until: { $0 })
旗帜。减少(false,{$0 || $1},直到:{$0})
#3
1
Try this piece of code:
试试这段代码:
extension Array {
var hasTrue:Bool {
for (idx, objectToCompare) in enumerate(self) {
if let to = objectToCompare as? Bool { if to { return true } }
}
return false
}
}
var flags:[Bool] = [false, false, true, false, false, true, false]
flags.hasTrue
#1
6
As others have suggested, you can use contains
for this purpose:
正如其他人所建议的,您可以为此目的使用contains:
var flags = [false, false, true, false, false, true, false]
contains(flags,true) //--> true
Another option is to use find
to search for the first instance of what you're looking for, in this case true
:
另一种选择是使用find来搜索您要查找的第一个实例,在本例中为真:
var flags = [false, false, true, false, false, true, false]
find(flags,true) // --> 2, returns nil if not found
let containsTrue = (find(flags,true) != nil)
#2
2
It's not available out of the box in the Swift Standard Library, but you can make it. In my blog post I have described my proposed solution. In your case it'll look like this on the call side:
在Swift标准库中,它是不可用的,但是您可以使用它。在我的博客中,我描述了我提出的解决方案。在你的情况下,在调用端看起来是这样的:
flags.reduce(false, { $0 || $1 }, until: { $0 })
旗帜。减少(false,{$0 || $1},直到:{$0})
#3
1
Try this piece of code:
试试这段代码:
extension Array {
var hasTrue:Bool {
for (idx, objectToCompare) in enumerate(self) {
if let to = objectToCompare as? Bool { if to { return true } }
}
return false
}
}
var flags:[Bool] = [false, false, true, false, false, true, false]
flags.hasTrue