我想要用一行Swift表达式找到类型为EKSourceType.Local
的第一个EKSource
。以下是我目前拥有的代码:
let eventSourceForLocal =
eventStore.sources[eventStore.sources.map({ $0.sourceType })
.indexOf(EKSourceType.Local)!]
有没有更好的方法可以做到这一点(例如不需要映射和/或使用find
的通用版本)?
另外在Swift4中您可以使用:
let local = eventStore.sources.first {$0.sourceType == .Local}
有一个带有谓词闭包的 indexOf
版本 - 使用它来查找第一个本地源的索引(如果存在),然后使用该索引在 eventStore.sources
上执行操作:
if let index = eventStore.sources.indexOf({ $0.sourceType == .Local }) {
let eventSourceForLocal = eventStore.sources[index]
}
或者,您可以通过对SequenceType
进行扩展来添加通用的find
方法:
extension SequenceType {
func find(@noescape predicate: (Self.Generator.Element) throws -> Bool) rethrows -> Self.Generator.Element? {
for element in self {
if try predicate(element) {
return element
}
}
return nil
}
}
let eventSourceForLocal = eventStore.sources.find({ $0.sourceType == .Local })
(为什么这个还没有出现?)
try
的问题已经解决了,你发现得不错。所有的序列操作都会消耗一个序列(map、contains 等等),所以我认为这不是问题所在。indexOf 很好用,但仅限于集合。 - Nate Cookfirst(where:)
方法,可以做到这一点。 - Nate Cook我不明白为什么你要使用map
,为什么不使用filter
呢?这样你最终将得到所有本地源,但实际上可能只有一个或者没有,你可以通过请求第一个源(如果没有,则是nil
)来轻松找出:
let local = eventStore.sources.filter{$0.sourceType == .Local}.first
let local = eventStore.sources.lazy.filter{$0.sourceType == .Local}.first
- Jeroen LeenartsSwift 4解决方案,也可以处理数组中没有元素与您的条件匹配的情况:
if let firstMatch = yourArray.first{$0.id == lookupId} {
print("found it: \(firstMatch)")
} else {
print("nothing found :(")
}
Swift 5:如果要从模型数组中查找,请指定 $0.keyTofound,否则请使用 $0。
if let index = listArray.firstIndex(where: { $0.id == lookupId }) {
print("Found at \(index)")
} else {
print("Not found")
}
let arr = [0,1,2,3]
let result = arr.lazy.map { print(""); return $0 }.first(where: { $0 == 2 })
print(result) // 3x then 2
这有什么酷的?对于Swift 3,您需要对Nate上面的答案进行一些小的更改。以下是Swift 3版本:
public extension Sequence {
func find(predicate: (Iterator.Element) throws -> Bool) rethrows -> Iterator.Element? {
for element in self {
if try predicate(element) {
return element
}
}
return nil
}
}
变更: SequenceType
改为 Sequence
,Self.Generator.Element
改为 Iterator.Element
let local = eventStore.sources.first {$0.sourceType == .Local}
。 (注:$0表示闭包中的第一个参数,这里指sources数组中的元素) - Nick Gaensfilter
然后first
是次优的,因为它强制执行最坏情况下的n
时间复杂度。这意味着即使在找到元素之后,filter
仍将循环遍历数组的其余部分。first(where:{})
短路遍历并在找到第一个匹配项后中断。 - Joe