作为一项学习练习,我将一些Underscore.js的实用程序函数移植到swift,我从some
开始,如果集合中有任何元素,则返回true传递一个给定的集合块。
天真的实施:
extension Sequence {
func some(_ predicate: (Self.Iterator.Element) -> Bool) -> Bool {
return reduce(false) { $0 || predicate($1) }
}
}
但我注意到很多STL功能包括throws
和rethrows
。一个很好的例子是filter
函数,它具有函数签名:
func filter(_ isIncluded: (Element) throws -> Bool) rethrows -> [Element]
有人可以告诉我如何编写some
功能,同时还可以使用throw
和rethrows
功能吗?
答案 0 :(得分:0)
此博客文章是一个很好的概述:http://robnapier.net/re-throws
基本上,rethrows
是一个指示,只有当一个闭包参数抛出时,函数才会抛出。如果你用一个没有抛出的闭包来调用函数,这会强制你不必处理抛出。在您的情况下,您只需将扩展方法定义为:
extension Sequence {
func some(_ predicate: (Self.Iterator.Element) throws -> Bool) rethrows -> Bool {
return reduce(false) { $0 || try predicate($1) }
}
}
现在,some
会接受投掷或非投掷谓词,如果你给它一个非投掷谓词,你就不必担心try
。
答案 1 :(得分:0)
我最终使用map
和reduce
的组合解决了我的问题。我做了一个快速的游乐场:
extension Sequence {
func some(_ predicate: (Self.Iterator.Element) throws -> Bool) rethrows -> Bool {
return try map(predicate).reduce(false) { $0 || $1 }
}
}
let list = [1, 2, 3]
list.some({ $0 == 1 }) // true
list.some({ $0 % 50 == 0 }) // false
使用map,将谓词应用于每个元素,将整个数组映射到bool数组,然后将它们组合在一起。
它不是最有效的算法,并且可以进行一些明确的优化,例如在遇到true
值时立即返回,但我确实喜欢它的简单功能性质溶液