【问题标题】:Is there a way to break from an array's reduce function in Swift?有没有办法打破 Swift 中数组的 reduce 函数?
【发布时间】:2015-07-06 13:21:49
【问题描述】:

有没有办法从 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) { $0 || $1 }

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

有没有办法让reduce() 也能在第三次迭代中退出(就像它可以在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 的方法。

【问题讨论】:

  • 我不这么认为。 reduce like containsfilter 遍历所有项目。我认为第一个例子是一个合适的例子
  • 你可以把它写成扩展。这看起来像减少但提前中断。
  • 你为什么不直接使用 contains?
  • 一般来说,如果你发现自己需要突破 reduce,你不应该使用 reduce。使用for 循环要好得多,而不是扭曲自己避免使用循环。如果您不喜欢它在代码中的外观,请将其包装在类似于 containsfind 的通用函数中,并在循环主体中使用早期的 return

标签: arrays swift break array-reduce


【解决方案1】:

正如其他人所建议的,您可以为此使用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)

【讨论】:

    【解决方案2】:

    它在 Swift 标准库中不是开箱即用的,但你可以做到。在my blog post 中,我描述了我提出的解决方案。在您的情况下,它在调用端看起来像这样:

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

    你可以在that Playground试试看

    【讨论】:

    • 请按照 Stack Overflow 政策的要求,在此处包含您博客文章中的相关内容。如果您的网站无限期下线,这将对人们有所帮助。
    • 你去@idmean
    猜你喜欢
    • 2011-06-04
    • 2015-03-08
    • 2016-11-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-19
    • 1970-01-01
    • 2022-01-07
    相关资源
    最近更新 更多