(Swift 3)
Überprüfen Sie, ob ein Element in einem Array vorhanden ist (das einige Kriterien erfüllt), und fahren Sie in diesem Fall mit dem ersten solchen Element fort
Wenn die Absicht ist:
- Um zu überprüfen, ob ein Element in einem Array vorhanden ist (/ einige boolesche Kriterien erfüllt, nicht unbedingt Gleichheitstests),
- Und wenn ja, fahren Sie fort und arbeiten Sie mit dem ersten solchen Element.
Dann eine Alternative zu contains(_:)
als blueprinted Sequence
ist first(where:)
von Sequence
:
let elements = [1, 2, 3, 4, 5]
if let firstSuchElement = elements.first(where: { $0 == 4 }) {
print(firstSuchElement) // 4
// ...
}
In diesem erfundenen Beispiel mag seine Verwendung albern erscheinen, aber es ist sehr nützlich, wenn Arrays nicht grundlegender Elementtypen nach der Existenz von Elementen abgefragt werden, die eine bestimmte Bedingung erfüllen. Z.B
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.
Alle verketteten Operationen mit .filter { ... some condition }.first
können vorteilhafterweise durch ersetzt werden first(where:)
. Letzteres zeigt die Absicht besser und hat Leistungsvorteile gegenüber möglichen nicht faulen Geräten von .filter
, da diese das gesamte Array passieren, bevor das (mögliche) erste Element, das den Filter passiert, extrahiert wird.
Überprüfen Sie, ob ein Element in einem Array vorhanden ist (das einige Kriterien erfüllt), und entfernen Sie in diesem Fall das erste derartige Element
Ein Kommentar unter Fragen:
Wie kann ich das firstSuchElement
aus dem Array entfernen ?
Ein ähnlicher Anwendungsfall wie oben besteht darin , das erste Element zu entfernen, das ein bestimmtes Prädikat erfüllt. Zu diesem Zweck kann die index(where:)
Methode von Collection
(die für die Array-Sammlung leicht verfügbar ist) verwendet werden, um den Index des ersten Elements zu finden, das das Prädikat erfüllt, wonach der Index mit der remove(at:)
Methode von Array
to (möglich; vorausgesetzt, dass er existiert) verwendet werden kann. Entfernen Sie dieses Element.
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"]
}
Wenn Sie das Element aus dem Array entfernen und damit arbeiten möchten , wenden Sie die Optional
folgende map(_:)
Methode an : s , um das Ergebnis von bedingt (für die .some(...)
Rückgabe von index(where:)
) zu verwenden index(where:)
, um das entfernte Element aus dem Array zu entfernen und zu erfassen (innerhalb einer optionalen Bindungsklausel). .
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
}
Beachten Sie, dass es sich bei dem erfundenen Beispiel oben um einfache Werttypen ( String
Instanzen) handelt. Die Verwendung eines Prädikats zum Auffinden eines bestimmten Elements ist daher etwas übertrieben , da wir die Gleichheit möglicherweise einfach mit der einfacheren index(of:)
Methode testen , wie in der Antwort von @ DogCoffee gezeigt . Wenn Sie jedoch den obigen Find-and-Remove-Ansatz auf das Person
Beispiel anwenden , ist die Verwendung index(where:)
mit einem Prädikat angemessen (da wir nicht mehr auf Gleichheit testen, sondern ein angegebenes Prädikat erfüllen).
if find(elements, 5) != nil { }
ist nicht gut genug