Подтвердить что ты не робот

Найдите условие согласования первого элемента в массиве Swift (например, EKSource)

Я хотел бы найти первый EKSource типа EKSourceType.Local с "одиночным" выражением строки в Swift. Вот что я сейчас имею:

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

Есть ли лучший способ сделать это (например, без отображения и/или с общей версией find)?

4b9b3361

Ответ 1

Там версия 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 })

(Почему этого уже нет?)

Ответ 2

Альтернативно в Swift3 вы можете использовать:

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

Ответ 3

Я не понимаю, почему вы используете map вообще. Почему бы не использовать filter? Затем вы получите все локальные источники, но на самом деле, вероятно, будет только один или ни один, и вы можете легко узнать, попросив первый (это будет nil, если его нет ):

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

Ответ 4

Для 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

Ответ 5

Попробуем что-то более функциональное:

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

Что круто об этом?
Вы получаете доступ к элементу или я во время поиска. И это функционально.