Найдите условие согласования первого элемента в массиве Swift (например, EKSource)
Я хотел бы найти первый EKSource
типа EKSourceType.Local
с "одиночным" выражением строки в Swift. Вот что я сейчас имею:
let eventSourceForLocal =
eventStore.sources[eventStore.sources.map({ $0.sourceType })
.indexOf(EKSourceType.Local)!]
Есть ли лучший способ сделать это (например, без отображения и/или с общей версией find
)?
Ответы
Ответ 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
Что круто об этом?
Вы получаете доступ к элементу или я во время поиска. И это функционально.