(Swift 3)
Überprüfen, ob ein Element in einem Array existiert (bestimmte Kriterien erfüllt), und falls ja, mit dem ersten solchen Element weiterarbeiten
Wenn die Absicht ist:
- Zu überprüfen, ob ein Element in einem Array existiert (/bestimmte boolesche Kriterien erfüllt, nicht unbedingt Gleichheitsprüfung),
- Und wenn ja, dann mit dem ersten solchen Element weiterarbeiten,
Dann ist eine Alternative zu contains(_:)
als blaubedruckt in Sequence
zu first(where:)
von Sequence
:
let elements = [1, 2, 3, 4, 5]
if let firstSuchElement = elements.first(where: { $0 == 4 }) {
print(firstSuchElement) // 4
// ...
}
In diesem konstruierten Beispiel mag die Verwendung vielleicht albern erscheinen, aber es ist sehr nützlich, wenn Arrays von nicht grundlegenden Elementtypen auf das Vorhandensein von Elementen geprüft werden, die eine 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) kann möglicherweise das Mietauto in Schweden fahren.")
// ...
} // Hannah kann möglicherweise das Mietauto in Schweden fahren.
let daniel = Person(18, "Daniel")
if let sameAgeAsDaniel = persons.first(where: { $0.age == daniel.age }) {
print("\(sameAgeAsDaniel.name) ist im selben Alter wie \(daniel.name).")
// ...
} // Sarah ist im selben Alter wie Daniel.
Alle verketteten Operationen mit .filter { ... some condition }.first
können vorteilhafterweise durch first(where:)
ersetzt werden. Letzteres zeigt die Absicht besser an und hat Leistungsvorteile gegenüber möglichen nicht-lazy Anwendungen von .filter
, da diese das gesamte Array passieren werden, bevor das (mögliche) erste Element, das den Filter passiert, extrahiert wird.
Überprüfen, ob ein Element in einem Array existiert (bestimmte Kriterien erfüllt), und falls ja, das erste solche Element entfernen
Ein Kommentar darunter fragt:
Wie kann ich das firstSuchElement
aus dem Array entfernen?
Ein ähnlicher Anwendungsfall wie der oben ist, das erste Element zu entfernen, das einem bestimmten Prädikat genügt. Dazu kann die Methode index(where:)
von Collection
(die für Arrays verfügbar ist) verwendet werden, um den Index des ersten Elements zu finden, das das Prädikat erfüllt, wonach der Index mit der Methode remove(at:)
von Array
verwendet werden kann, um dieses Element zu entfernen (falls es existiert).
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"]
}
Oder, wenn Sie das Element aus dem Array entfernen und damit arbeiten möchten, wenden Sie die Optional
s map(_:)
Methode an, um bedingt (für ein .some(...)
Ergebnis von index(where:)
) das Ergebnis von index(where:)
zum Entfernen und Erfassen des entfernten Elements aus dem Array zu verwenden (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) }) {
// Wenn wir hier eintreten, wurde das erste solche Element jetzt
// aus dem Array entfernt
print(elements) // ["a", "b", "d", "e", "a", "b", "c"]
// und wir können damit arbeiten
print(firstSuchElement) // c
}
Beachten Sie, dass in dem konstruierten obigen Beispiel die Array-Elemente einfache Werttypen (String
-Instanzen) sind, daher ist es etwas übertrieben, ein Prädikat zu verwenden, um ein bestimmtes Element zu finden. Stattdessen könnten wir einfach mit der einfacheren Methode index(of:)
die Gleichheit überprüfen, wie in der Antwort von @DogCoffee gezeigt. Wenn wir jedoch den Find-and-Remove-Ansatz auf das Person
-Beispiel anwenden, ist die Verwendung von index(where:)
mit einem Prädikat angemessen (da wir nicht mehr auf Gleichheit, sondern auf die Erfüllung eines bereitgestellten Prädikats prüfen).