Find first element matching condition in Swift array (e.g. EKSource)

 ̄綄美尐妖づ 提交于 2019-11-30 02:46:18

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?)

Alternatively in Swift3 you could use:

let local = eventStore.sources.first(where: {$0.sourceType == .Local}) 

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

Swift 4 solution that also handles the situation when there are no elements in your array that match your condition:

if let firstMatch = yourArray.first{$0.id == lookupId} {
  print("found it: \(firstMatch)")
} else {
  print("nothing found :(")
}

Let's try something more functional:

let arr = [0,1,2,3]
let result = arr.lazy.map{print("💥");return $0}.first(where: {$0 == 2})
print(result)//3x 💥 then 2

Whats cool about this?
You get access to element or i while you search. And it's functional.

For Swift 3 you'll need to make a few small changes to Nate's answer above. Here's the Swift 3 version:

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
    }
}

Changes: SequenceType > Sequence, Self.Generator.Element > Iterator.Element

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!