在Swift数组中找到第一个元素匹配条件(例如EKSource)

Dru*_*rux 34 ios eventkit swift ios9 swift2

我想在Swift中找到第一个带有"单"线表达式EKSource的类型EKSourceType.Local.这是我目前拥有的:

let eventSourceForLocal = 
    eventStore.sources[eventStore.sources.map({ $0.sourceType })
        .indexOf(EKSourceType.Local)!]
Run Code Online (Sandbox Code Playgroud)

有没有更好的方法(例如没有映射和/或通用版本find)?

Bue*_*eno 83

或者在Swift3中你可以使用:

let local = eventStore.sources.first(where: {$0.sourceType == .Local}) 
Run Code Online (Sandbox Code Playgroud)

  • 在Swift4中,它变成:`let local = eventStore.sources.first {$ 0.sourceType == .Local}` (13认同)

Nat*_*ook 37

有一个版本indexOf需要谓词闭包 - 使用它来查找第一个本地源的索引(如果存在),然后使用该索引eventStore.sources:

if let index = eventStore.sources.indexOf({ $0.sourceType == .Local }) {
    let eventSourceForLocal = eventStore.sources[index]
}
Run Code Online (Sandbox Code Playgroud)

或者,您可以find通过以下扩展名添加通用方法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 })
Run Code Online (Sandbox Code Playgroud)

(为什么不在那里?)

  • @DanielGalasko好消息,Swift 3现在包含一个`first(where:)`方法,它就是这样做的序列. (12认同)
  • 链接到提案https://github.com/apple/swift-evolution/blob/master/proposals/0032-sequencetype-find.md (2认同)

mat*_*att 19

我不明白你为什么要使用它map.为什么不用filter?然后你会得到所有本地资源,但实际上可能只有一个,或者没有,你可以通过询问第一个来找到答案(nil如果没有的话):

let local = eventStore.sources.filter{$0.sourceType == .Local}.first
Run Code Online (Sandbox Code Playgroud)

  • 虽然这是最直接的解决方案,但它的缺点是始终过滤整个集合,即使它只需要第一个匹配元素.我并不是在提倡过早优化,而是提倡可能很重要的大型系列. (25认同)
  • IMO过早优化甚至没有在这里发挥作用 - 避免完全不必要的工作既不早熟也不优化. (6认同)
  • @DanielRinser我同意,我更喜欢Nate Cook的回答. (3认同)

bud*_*ino 13

Swift 4解决方案,当数组中没有符合您条件的元素时,它也会处理这种情况:

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


Gur*_*ngh 6

Swift 5如果您想从模型数组中查找,请指定$0.keyTofound否则使用$0

if let index = listArray.firstIndex(where: { $0.id == lookupId }) {
     print("Found at \(index)")
} else {
     print("Not found")
 }
Run Code Online (Sandbox Code Playgroud)