有没有办法打破Swift中数组的reduce函数?

时间:2015-04-27 22:02:16

标签: arrays swift break array-reduce

有没有办法在break循环中执行与for类似的操作,但在数组的reduce()函数中呢?

E.g。考虑我有一个数组:

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) { $0 || $1 }

但是,对于示例中给出的数组,for循环体仅执行3次,而reduce()函数闭包将被触发7次。

有没有办法让reduce()在第3次迭代中拯救(就像在for循环中可以做到的那样)?

[UPD]

我过分简化了这个问题。最初的问题更像是这样:

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)
}

...即我有一个对象数组,我想知道是否至少有一个对象的某些方法评估为true

2 个答案:

答案 0 :(得分:8)

正如其他人所建议的那样,您可以将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)

答案 1 :(得分:3)

它在Swift标准库中没有开箱即用,但您可以制作它。在my blog post我已经描述了我提出的解决方案。在你的情况下,它在呼叫方面看起来像这样:

flags.reduce(false, { $0 || $1 }, until: { $0 })