如果xs
是一个集合,pred
是一个返回Bool
的闭包,是否有一个内置函数可以执行以下操作?
xs.filter(pred).first
这将获取与预测匹配的集合的第一个元素,如果没有匹配,则获取 nil 。对索引不感兴趣,而是对元素本身感兴趣。
最佳答案
不,没有,但你可以自己写一个,如下所示:
extension SequenceType {
func first(@noescape pred: Generator.Element throws -> Bool) rethrows -> Generator.Element? {
return try filter(pred).first
}
}
编辑:此版本不是最佳版本,因为 filter
创建了一个全新的数组,即使只需要第一个元素。正如 Martin R 所指出的,lazy.filter 也不起作用。这对于使其与lazy
一起工作是必要的:
extension CollectionType {
func first(pred: Generator.Element -> Bool) -> Generator.Element? {
return lazy.filter(pred).first
}
}
因为:
@noescape
不能使用,因为@noescape
意味着闭包无法转义当前函数,而将其传递给惰性时可能会出现这种情况过滤器
(在被要求之前不会评估元素 -> 必须转义谓词)throws
不能使用,因为过滤器是惰性的 -> 错误不会立即抛出,而是在第一次使用时抛出,即调用first< 时
,但first
不能抛出,因为它是一个属性。有一些关于在 Swift 的 future 版本中使用 getter(和下标)进行抛出的讨论。- 必须使用
CollectionType
,因为只有LazyCollectionType
具有first
属性。
因此,要真正使其变得懒惰并拥有所有 @noescape
、throws
和 SequenceType
,您必须使用命令式方法:
extension SequenceType {
func first(@noescape pred: Generator.Element throws -> Bool) rethrows -> Generator.Element? {
for elem in self where try pred(elem) {
return elem
}
return nil
}
}
关于Swift 函数查找集合中与谓词匹配的第一个元素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34031754/