(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 Sequenceist 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 }.firstkö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 firstSuchElementaus 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 Arrayto (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 Optionalfolgende 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 ( StringInstanzen) 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 PersonBeispiel 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