(Swift 3)
Verifique si un elemento existe en una matriz (cumpliendo algunos criterios), y si es así, continúe trabajando con el primer elemento
Si la intención es:
- Para verificar si un elemento existe en una matriz (/ cumple algunos criterios booleanos, no necesariamente pruebas de igualdad),
- Y si es así, proceda y trabaje con el primer elemento,
Entonces, una alternativa a contains(_:)
blueprinted Sequence
es first(where:)
de Sequence
:
let elements = [1, 2, 3, 4, 5]
if let firstSuchElement = elements.first(where: { $0 == 4 }) {
print(firstSuchElement) // 4
// ...
}
En este ejemplo artificial, su uso puede parecer tonto, pero es muy útil si se consultan matrices de tipos de elementos no fundamentales para la existencia de cualquier elemento que cumpla alguna condición. P.ej
struct Person {
let age: Int
let name: String
init(_ age: Int, _ name: String) {
self.age = age
self.name = name
}
}
let persons = [Person(17, "Fred"), Person(16, "Susan"),
Person(19, "Hannah"), Person(18, "Sarah"),
Person(23, "Sam"), Person(18, "Jane")]
if let eligableDriver = persons.first(where: { $0.age >= 18 }) {
print("\(eligableDriver.name) can possibly drive the rental car in Sweden.")
// ...
} // Hannah can possibly drive the rental car in Sweden.
let daniel = Person(18, "Daniel")
if let sameAgeAsDaniel = persons.first(where: { $0.age == daniel.age }) {
print("\(sameAgeAsDaniel.name) is the same age as \(daniel.name).")
// ...
} // Sarah is the same age as Daniel.
Cualquier operación encadenada usando .filter { ... some condition }.first
puede ser reemplazada favorablemente por first(where:)
. Este último muestra una mejor intención y tiene ventajas de rendimiento sobre los posibles dispositivos no perezosos .filter
, ya que estos pasarán la matriz completa antes de extraer el (posible) primer elemento que pasa el filtro.
Compruebe si existe un elemento en una matriz (cumpliendo algunos criterios) y , de ser así, elimine el primer elemento
Un comentario debajo de las consultas:
¿Cómo puedo eliminar el firstSuchElement
de la matriz?
Un caso de uso similar al anterior es eliminar el primer elemento que cumple un predicado dado. Para hacerlo, el index(where:)
método de Collection
(que está fácilmente disponible para la colección de matrices) puede usarse para encontrar el índice del primer elemento que cumple el predicado, después de lo cual el índice puede usarse con el remove(at:)
método de Array
to (posible; dado que existe) eliminar ese elemento
var elements = ["a", "b", "c", "d", "e", "a", "b", "c"]
if let indexOfFirstSuchElement = elements.index(where: { $0 == "c" }) {
elements.remove(at: indexOfFirstSuchElement)
print(elements) // ["a", "b", "d", "e", "a", "b", "c"]
}
O, si desea eliminar el elemento de la matriz y trabajar con él , aplique Optional
el map(_:)
método : s para usar condicionalmente (para .some(...)
regresar de index(where:)
) el resultado de index(where:)
eliminar y capturar el elemento eliminado de la matriz (dentro de una cláusula de enlace opcional) .
var elements = ["a", "b", "c", "d", "e", "a", "b", "c"]
if let firstSuchElement = elements.index(where: { $0 == "c" })
.map({ elements.remove(at: $0) }) {
// if we enter here, the first such element have now been
// remove from the array
print(elements) // ["a", "b", "d", "e", "a", "b", "c"]
// and we may work with it
print(firstSuchElement) // c
}
Tenga en cuenta que en el ejemplo artificial anterior, los miembros de la matriz son tipos de valores simples ( String
instancias), por lo que usar un predicado para encontrar un miembro dado es algo excesivo, ya que podríamos simplemente probar la igualdad usando el index(of:)
método más simple como se muestra en la respuesta de @ DogCoffee . Person
Sin embargo, si aplica el enfoque de buscar y eliminar anterior al ejemplo, usarlo index(where:)
con un predicado es apropiado (ya que ya no probamos la igualdad sino el cumplimiento de un predicado proporcionado).
if find(elements, 5) != nil { }
¿No es suficientemente bueno?