ios - Encuentre la condición de coincidencia del primer elemento en la matriz Swift(por ejemplo, EKSource)
swift2 ios9 (6)
Probemos algo más funcional:
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
}
}
¿Qué tiene de bueno esto?
Obtienes acceso a element o i mientras buscas. Y es funcional.
Me gustaría encontrar el primer EKSource
de tipo EKSourceType.Local
con una expresión de "única" línea en Swift. Esto es lo que tengo actualmente:
let eventSourceForLocal =
eventStore.sources[eventStore.sources.map({ $0.sourceType })
.indexOf(EKSourceType.Local)!]
¿Hay una forma mejor de hacerlo (como sin mapear y / o con una versión genérica de find
)?
Alternativamente en Swift3 puedes usar:
let local = eventStore.sources.first(where: {$0.sourceType == .Local})
Hay una versión de indexOf
que requiere un cierre de predicado; indexOf
para encontrar el índice de la primera fuente local (si existe) y luego use ese índice en eventStore.sources
:
if let index = eventStore.sources.indexOf({ $0.sourceType == .Local }) {
let eventSourceForLocal = eventStore.sources[index]
}
Alternativamente, podría agregar un método de find
genérico a través de una extensión en 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 })
(¿Por qué no está ya allí?)
No entiendo por qué estás usando el map
en absoluto. ¿Por qué no usar filter
? Luego terminarás con todas las fuentes locales, pero en realidad, probablemente solo habrá una o ninguna, y puedes averiguarlo fácilmente preguntando por la primera (será nil
si no hay una):
let local = eventStore.sources.filter{$0.sourceType == .Local}.first
Para Swift 3 tendrá que hacer algunos pequeños cambios en la respuesta de Nate anterior. Aquí está la versión Swift 3:
if let firstMatch = yourArray.first{$0.id == lookupId} {
print("found it: /(firstMatch)")
} else {
print("nothing found :(")
}
Cambios: SequenceType
> Sequence
, Self.Generator.Element
> Self.Generator.Element
La solución Swift 4 que también maneja la situación cuando no hay elementos en su matriz que coincidan con su condición:
let arr = [0,1,2,3]
let result = arr.lazy.map{print("💥");return $0}.first(where: {$0 == 2})
print(result)//3x 💥 then 2