Find first element matching condition in Swift array (e.g. EKSource)
I would like to find the first EKSource
of type EKSourceType.Local
with a "single"-line expression in Swift. Here is what I currently have:
let eventSourceForLocal =
eventStore.sources[eventStore.sources.map({ $0.sourceType })
.indexOf(EKSourceType.Local)!]
Is there a better way of doing this (such as without mapping and/or with a generic version of find
)?
Solution 1:
Alternatively in Swift3 you could use:
let local = eventStore.sources.first(where: {$0.sourceType == .Local})
Solution 2:
There's a version of indexOf
that takes a predicate closure - use it to find the index of the first local source (if it exists), and then use that index on eventStore.sources
:
if let index = eventStore.sources.indexOf({ $0.sourceType == .Local }) {
let eventSourceForLocal = eventStore.sources[index]
}
Alternately, you could add a generic find
method via an extension on SequenceType
:
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 })
(Why isn't this there already?)
Solution 3:
I don't understand why you're using map
at all. Why not use filter
? You will then end up with all the local sources, but in actual fact there will probably be only one, or none, and you can readily find out by asking for the first one (it will be nil
if there isn't one):
let local = eventStore.sources.filter{$0.sourceType == .Local}.first