在reduce中使用逻辑运算符作为组合闭包

时间:2016-01-09 22:16:49

标签: swift functional-programming swift2 closures logical-operators

我试图通过使用以下代码应用逻辑运算符 OR Bool)来减少||数组,但是我收到错误:

func reduceBools(values: [Bool]) -> Bool {
    return values.reduce(false, combine: ||)
}
  

对成员'||'的歧义提及

类似于整数,代码就像魅力一样。

func reduceInts(values: [Int]) -> Int {
    return values.reduce(0, combine: +)
}

我能够通过添加||函数(下面的代码)或使用{ $0 || $1 }闭包来使其工作,但我不喜欢这些方法,我宁愿简单地传递运算符。

func ||(lhs: Bool, rhs: Bool) -> Bool {
    return lhs || rhs
}

逻辑 AND &&)运算符也会发生同样的事情。

如何在不使用上述黑客的情况下使其正常工作?

5 个答案:

答案 0 :(得分:26)

作为替代方案,您可以使用以下方法

// ||
func reduceBoolsOr(values: [Bool]) -> Bool {
    return values.contains(true)
}

// &&
func reduceBoolsAnd(values: [Bool]) -> Bool {
    return !values.contains(false)
}

请注意.reduce comes with an overhead。如果最终结果是您问题的重要性(而不是在此上下文中查询||&&运算符的意外行为),那么上面的实用方法也许可以有帮助,即使它没有真正减少数组,但由于布尔类型的简单性质,产生相同的结果。

答案 1 :(得分:2)

对成员'||'的模糊引用意味着,有多个可能的候选者,编译器无法从中选择。在你的情况下那些是

public func ||<T : BooleanType, U : BooleanType>(lhs: T, @autoclosure rhs: () throws -> U) rethrows -> Bool

public func ||<T : BooleanType>(lhs: T, @autoclosure rhs: () throws -> Bool) rethrows -> Bool

可能你使用{ $0 || $1 }的'hack'是最好的解决方案。

答案 2 :(得分:0)

以下方法将起作用

values.reduce(false) { $0 || $1 }

答案 3 :(得分:0)

这是另一种方法,我修改了reduceBools函数以将运算符作为参数-

typealias LogicalOperator = ((Bool, @autoclosure () throws -> Bool) throws -> Bool)

func reduceBools(values: [Bool], combine: LogicalOperator) -> Bool {
    var started: Bool = false
    return values.reduce(into: true, { (result, value) in
        result = started ? try! combine(result, value) : value // obviously up to you how you'd handle the try/catch
        started = true
    })
}

let bools = [true, false, false, true]

let result1 = self.reduceBools(values: bools, combine: ||)
print(result1) // prints true

let result2 = self.reduceBools(values: bools, combine: &&)
print(result2) // prints false

或者作为Sequence的扩展可能更有用-

extension Sequence where Element == Bool {

    func reduce(_ combine: LogicalOperator) -> Bool {
        var started: Bool = false
        return self.reduce(into: true, { (result, value) in
            result = started ? try! combine(result, value) : value
            started = true
        })
    }
}

print(bools.reduce(||)) // prints true

答案 4 :(得分:0)

Swift 4.2+ / Xcode 10.0 +

Swift的现代版本中,有allSatisfy函数可以检查所有元素是否满足某些规则。


在OP的情况下:

values.allSatisfy { $0 }