(Swift 3)
Controlla se esiste un elemento in un array (soddisfacendo alcuni criteri) e, in tal caso, continua a lavorare con il primo di tali elementi
Se l'intento è:
- Per verificare se esiste un elemento in un array (/ soddisfa alcuni criteri booleani, non necessariamente test di uguaglianza),
- E in tal caso, procedere e lavorare con il primo di tali elementi,
Quindi un'alternativa a contains(_:)
come progetto Sequence
è first(where:)
di Sequence
:
let elements = [1, 2, 3, 4, 5]
if let firstSuchElement = elements.first(where: { $0 == 4 }) {
print(firstSuchElement) // 4
// ...
}
In questo esempio inventato, il suo utilizzo potrebbe sembrare sciocco, ma è molto utile se si interrogano array di tipi di elementi non fondamentali per l'esistenza di qualsiasi elemento che soddisfi una condizione. Per esempio
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.
Qualsiasi operazione concatenata che utilizza .filter { ... some condition }.first
può essere sostituita favorevolmente con first(where:)
. Quest'ultimo mostra un intento migliore e presenta vantaggi in termini di prestazioni rispetto a possibili dispositivi non pigri .filter
, poiché questi passeranno all'intero array prima di estrarre il (possibile) primo elemento che passa attraverso il filtro.
Controllare se esiste un elemento in un array (soddisfacendo alcuni criteri) e, in tal caso, rimuovere il primo di tali elementi
Un commento sotto le domande:
Come posso rimuovere firstSuchElement
l'array?
Un caso d'uso simile a quello sopra è quello di rimuovere il primo elemento che soddisfa un dato predicato. Per fare ciò, il index(where:)
metodo di Collection
(che è prontamente disponibile per la raccolta di array) può essere usato per trovare l'indice del primo elemento che soddisfa il predicato, dopodiché l'indice può essere usato con il remove(at:)
metodo di Array
(possibile; dato che esiste) rimuovi quell'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"]
}
Oppure, se si desidera rimuovere l'elemento dall'array e lavorare con , applicare Optional
il map(_:)
metodo : s per utilizzare in modo condizionale (per il .some(...)
ritorno da index(where:)
) il risultato da index(where:)
per rimuovere e acquisire l'elemento rimosso dall'array (all'interno di una clausola di associazione facoltativa) .
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
}
Si noti che nell'esempio inventato sopra i membri dell'array sono semplici tipi di valore ( String
istanze), quindi l'uso di un predicato per trovare un determinato membro è un po 'eccessivo, poiché potremmo semplicemente testare l'uguaglianza usando il index(of:)
metodo più semplice come mostrato nella risposta di @ DogCoffee . Se si applica l'approccio trova-rimuovi sopra Person
nell'esempio, tuttavia, index(where:)
è appropriato l' utilizzo con un predicato (poiché non testiamo più l'uguaglianza ma per soddisfare un predicato fornito).
if find(elements, 5) != nil { }
non è abbastanza buono?