我了解Swift的高阶函数,如Map,Filter,Reduce和FlatMap,但我不知道任何类似的' All'或者'任何'返回一个布尔值,在枚举结果的同时在阳性测试中发生短路。
例如,假设您拥有10,000个对象的集合,每个对象都有一个名为isFulfilled
的属性,并且您希望查看该集合中是否有isFulfilled
设置为false。在C#中,您可以使用myObjects.Any(obj -> !obj.isFulfilled)
,当该条件被命中时,它会使枚举的其余部分短路并立即返回true
。
Swift中有没有这样的东西?
答案 0 :(得分:5)
Sequence
(特别是Collection
和Array
)有一个(短路)contains(where:)
方法,将布尔谓词作为参数。例如,
if array.contains(where: { $0 % 2 == 0 })
检查数组是否包含任何偶数。
没有"所有"方法,但您也可以使用contains()
通过否定谓词和结果。例如,
if !array.contains(where: { $0 % 2 != 0 })
检查数组中所有数字是否均匀。当然,您可以定义自定义扩展方法:
extension Sequence {
func allSatisfy(_ predicate: (Iterator.Element) -> Bool) -> Bool {
return !contains(where: { !predicate($0) } )
}
}
如果你想允许"投掷"谓语的方式与
contains
方法然后将其定义为
extension Sequence {
func allSatisfy(_ predicate: (Iterator.Element) throws -> Bool) rethrows -> Bool {
return try !contains(where: { try !predicate($0) } )
}
}
更新:正如James Shapiro正确注意到的那样, Swift 4.2 中的allSatisfy
类型添加了Sequence
方法(目前处于测试阶段) ),见
(需要最近的4.2开发者快照。)
答案 1 :(得分:3)
你可以在Swift中做的另一件事就是"短路"在这种情况下,使用集合的lazy
属性,这会将您的实现更改为以下内容:
myObjects.lazy.filter({ !$0.isFulfilled }).first != nil
它与您要求的不完全相同,但在处理这些高阶函数时可能有助于提供另一种选择。您可以在Apple的文档中详细了解lazy
。在此编辑中,文档包含以下内容:
var lazy:LazyCollection>这个系列的视图 它提供了通常渴望操作的惰性实现,例如 作为地图和过滤器。
var lazy:LazySequence>含有它的序列 元素作为这个序列,但在其中的一些操作,如map 和过滤,懒洋洋地实施。
答案 2 :(得分:0)
如果你拥有该数组中的所有对象,它们应该符合一些协议,它实现了变量isFulfilled ...正如你所看到的,你可以让这些对象变为混淆(让我们称之为满意的协议) )...现在您可以将该数组转换为[FulfilledItem]类型......现在您可以继续使用
我在这里粘贴代码以便您更好地理解:
你看,你不能扩展Any或AnyObject,因为AnyObject是协议而且不能扩展(我猜想是Apple的意思),但你可以,sublass"协议或您喜欢称之为专业 - 使协议继承自AnyObject ...
protocol FulfilledItem: AnyObject{
var isFulfilled: Bool {get set}
}
class itemWithTrueValue: FulfilledItem{
var isFulfilled: Bool = true
}
class itemWithFalseValue: FulfilledItem{
var isFulfilled: Bool = false
}
var arrayOfFulFilled: [FulfilledItem] = [itemWithFalseValue(),itemWithFalseValue(),itemWithFalseValue(),itemWithFalseValue(),itemWithFalseValue(),itemWithFalseValue()]
let boolValue = arrayOfFulFilled.contains(where: {
$0.isFulfilled == false
})
现在我们已经拥有了一个非常好看的自定义协议,继承了所有Any属性+我们漂亮的isFulfilled属性,我们现在将通常处理...
根据苹果文档:
AnyObject仅用于引用类型(类),Any用于值和引用类型,所以我想它更喜欢继承AnyObject ...
现在您将AnyObject转换为数组协议项FulfilledItem,您将拥有漂亮的解决方案(不要忘记每个项目符合该协议并设置值......)
祝快乐编码:)