web-dev-qa-db-ja.com

Swift配列(EKSourceなど)で条件に一致する最初の要素を見つける

Swiftで「単一」行式を持つEKSourceType.Local型の最初のEKSourceを見つけたいです。現在私が持っているものは次のとおりです。

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

これを行うためのより良い方法がありますか(マッピングなしおよび/またはfindの汎用バージョンを使用するなど)?

33
Drux

述語閉包を取るindexOfのバージョンがあります-最初のローカルソース(存在する場合)のインデックスを検索し、eventStore.sourcesでそのインデックスを使用します。

if let index = eventStore.sources.indexOf({ $0.sourceType == .Local }) {
    let eventSourceForLocal = eventStore.sources[index]
}

または、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 })

(なぜこれが既にないのですか?)

38
Nate Cook

あるいは、Swift3では次を使用できます。

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

mapを使用している理由がまったくわかりません。 filterを使用しないのはなぜですか?その後、すべてのローカルソースが作成されますが、実際にはおそらく1つしか存在しないか、まったく存在しないため、最初のソースを要求することで簡単に見つけることができます(存在する場合はnilになります) 't one):

let local = eventStore.sources.filter{$0.sourceType == .Local}.first
19
matt

Swift 4条件に一致する要素が配列にない場合にも状況を処理するソリューション:

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

より機能的なものを試してみましょう:

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

これについてのクールな点は?
検索中に要素またはiにアクセスできます。そしてそれは機能的です。

2
eonist

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> SequenceSelf.Generator.Element> Iterator.Element

1
Tyler Sheaffer