In Objective-C, wenn ich ein Array habe
NSArray *array;
und ich möchte überprüfen, ob es nicht leer ist, ich mache immer:
if (array.count > 0) {
NSLog(@"There are objects!");
} else {
NSLog(@"There are no objects...");
}
Auf diese Weise muss nicht überprüft werden, ob array == nil
der Code in dieser Situation in den else
Fall fällt, und ein nicht nil
leeres Array würde dies tun.
In Swift bin ich jedoch auf die Situation gestoßen, in der ich ein optionales Array habe:
var array: [Int]?
und ich bin nicht in der Lage herauszufinden, welche Bedingung zu verwenden ist. Ich habe einige Optionen, wie:
Option A: Überprüfen Sie sowohl nicht nil
als auch leere Fälle im selben Zustand:
if array != nil && array!.count > 0 {
println("There are objects")
} else {
println("No objects")
}
Option B: Lösen Sie die Bindung des Arrays mit let
:
if let unbindArray = array {
if (unbindArray.count > 0) {
println("There are objects!")
} else {
println("There are no objects...")
}
} else {
println("There are no objects...")
}
Option C: Verwenden des von Swift bereitgestellten Koaleszenzoperators:
if (array?.count ?? 0) > 0 {
println("There are objects")
} else {
println("No objects")
}
Ich mag die Option B nicht sehr, weil ich Code unter zwei Bedingungen wiederhole. Ich bin mir jedoch nicht sicher, ob die Optionen A und C korrekt sind oder ob ich eine andere Methode verwenden sollte.
Ich weiß, dass die Verwendung eines optionalen Arrays je nach Situation vermieden werden kann, aber in einigen Fällen kann es erforderlich sein, zu fragen, ob es leer ist. Ich würde gerne wissen, wie es am einfachsten geht.
BEARBEITEN:
Wie @vacawama betonte, funktioniert diese einfache Art der Überprüfung:
if array?.count > 0 {
println("There are objects")
} else {
println("No objects")
}
Ich habe jedoch den Fall ausprobiert, in dem ich etwas Besonderes nur dann tun möchte, wenn es nil
leer oder leer ist, und dann fortfahren möchte, unabhängig davon, ob das Array Elemente enthält oder nicht. Also habe ich versucht:
if array?.count == 0 {
println("There are no objects")
}
// Do something regardless whether the array has elements or not.
Und auch
if array?.isEmpty == true {
println("There are no objects")
}
// Do something regardless whether the array has elements or not.
Aber wenn Array ist nil
, fällt es nicht in den if
Körper. Und das liegt daran, dass in diesem Fall array?.count == nil
und array?.isEmpty == nil
so die Ausdrücke array?.count == 0
und array?.isEmpty == true
beide ausgewertet werden false
.
Ich versuche also herauszufinden, ob es eine Möglichkeit gibt, dies auch mit nur einer Bedingung zu erreichen.
A
ist am besten lesbar. Das ist das Einzige, worauf Sie achten sollten.Antworten:
Aktualisierte Antwort für Swift 3 und höher:
Swift 3 hat die Möglichkeit zum Vergleichen von Optionen mit
>
und entfernt<
, sodass einige Teile der vorherigen Antwort nicht mehr gültig sind.Es ist weiterhin möglich, Optionen mit zu vergleichen.
==
Der einfachste Weg, um zu überprüfen, ob ein optionales Array Werte enthält, ist:if array?.isEmpty == false { print("There are objects!") }
Andere Möglichkeiten:
if array?.count ?? 0 > 0 { print("There are objects!") } if !(array?.isEmpty ?? true) { print("There are objects!") } if array != nil && !array!.isEmpty { print("There are objects!") } if array != nil && array!.count > 0 { print("There are objects!") } if !(array ?? []).isEmpty { print("There are objects!") } if (array ?? []).count > 0 { print("There are objects!") } if let array = array, array.count > 0 { print("There are objects!") } if let array = array, !array.isEmpty { print("There are objects!") }
Wenn Sie etwas tun möchten, wenn das Array
nil
leer ist oder ist, haben Sie mindestens 6 Möglichkeiten:Option A:
if !(array?.isEmpty == false) { print("There are no objects") }
Option B:
if array == nil || array!.count == 0 { print("There are no objects") }
Option C:
if array == nil || array!.isEmpty { print("There are no objects") }
Option D:
if (array ?? []).isEmpty { print("There are no objects") }
Option E:
if array?.isEmpty ?? true { print("There are no objects") }
Option F:
if (array?.count ?? 0) == 0 { print("There are no objects") }
Option C erfasst genau, wie Sie es auf Englisch beschrieben haben: "Ich möchte etwas Besonderes nur tun, wenn es null oder leer ist." Ich würde empfehlen, dass Sie dies verwenden, da es leicht zu verstehen ist. Daran ist nichts auszusetzen, zumal es "kurzschließt" und die Prüfung auf leer überspringt, wenn die Variable ist
nil
.Vorherige Antwort für Swift 2.x:
Sie können einfach tun:
if array?.count > 0 { print("There are objects") } else { print("No objects") }
Wie @Martin in den Kommentaren hervorhebt,
func ><T : _Comparable>(lhs: T?, rhs: T?) -> Bool
bedeutet dies, dass der Compiler0
als Wraps umschließt,Int?
damit der Vergleich mit der linken Seite durchgeführt werden kann, wasInt?
auf den optionalen Verkettungsaufruf zurückzuführen ist.In ähnlicher Weise könnten Sie Folgendes tun:
if array?.isEmpty == false { print("There are objects") } else { print("No objects") }
Hinweis: Damit
false
dies funktioniert, müssen Sie explizit mit hier vergleichen .Wenn Sie etwas tun möchten, wenn das Array
nil
leer ist oder ist, haben Sie mindestens 7 Möglichkeiten:Option A:
if !(array?.count > 0) { print("There are no objects") }
Option B:
if !(array?.isEmpty == false) { print("There are no objects") }
Option C:
if array == nil || array!.count == 0 { print("There are no objects") }
Option D:
if array == nil || array!.isEmpty { print("There are no objects") }
Option E:
if (array ?? []).isEmpty { print("There are no objects") }
Option F:
if array?.isEmpty ?? true { print("There are no objects") }
Option G:
if (array?.count ?? 0) == 0 { print("There are no objects") }
Option D erfasst genau, wie Sie es auf Englisch beschrieben haben: "Ich möchte etwas Besonderes nur tun, wenn es null oder leer ist." Ich würde empfehlen, dass Sie dies verwenden, da es leicht zu verstehen ist. Daran ist nichts auszusetzen, zumal es "kurzschließt" und die Prüfung auf leer überspringt, wenn die Variable ist
nil
.quelle
func ><T : _Comparable>(lhs: T?, rhs: T?) -> Bool
Operator verwendet und die rechte Seite0
wirdInt?
vom Compiler in einen eingeschlossen .var opt : Int? = nil
,opt < 0
bewertettrue
. Es ist hier nicht relevant , sondern kann unerwartet sein, und kann ein Argument gegen den Vergleich optional ganze Zahlen.nil
ist kleiner als jeder Nicht-Null-Wert, denInt
Sie darauf werfen, auch negative. Es muss sich an dem einen oder anderen Ende des umschlossenen Typs befinden, da jede Implementierung von<
eine Gesamtreihenfolge sein muss und optional jeden vergleichbaren Typ umschließen kann. Ich denke, nichts weniger als alles andere ist intuitiv, denn wenn jemand eine Spalte mit Zahlen sortiert, die leer sein könnte, würde er erwarten, dass die Leerzeichen vor 1 stehen. Oder alternativ ist eine Null-Array-Variable noch leerer als eine leere Array :)!(array?.isEmpty == false)
wird sein,true
wennarray
istnil
, aberarray?.isEmpty == true
wird sein,false
wennarray
ist,nil
weilnil
nicht gleich isttrue
. Wir wollen einnil
array
als leer behandeln.Erweiterungseigenschaft im
Collection
Protokoll* Geschrieben in Swift 3
extension Optional where Wrapped: Collection { var isNilOrEmpty: Bool { switch self { case .some(let collection): return collection.isEmpty case .none: return true } } }
Beispiel Verwendung:
if array.isNilOrEmpty { print("The array is nil or empty") }
Andere Optionen
Abgesehen von der obigen Erweiterung finde ich die folgende Option am klarsten, ohne das gewaltsame Auspacken von Optionen zu erzwingen. Ich habe dies als Auspacken des optionalen Arrays und als Ersatz für ein leeres Array des gleichen Typs gelesen. Nehmen Sie dann das (nicht optionale) Ergebnis und
isEmpty
führen Sie den bedingten Code aus.Empfohlen
if (array ?? []).isEmpty { print("The array is nil or empty") }
Obwohl das Folgende klar liest, schlage ich die Gewohnheit vor, das Auspacken von Optionen nach Möglichkeit zu vermeiden. Obwohl Sie garantiert , dass
array
niemals sein wird,nil
wennarray!.isEmpty
in diesem speziellen Fall ausgeführt wird, wäre es später leicht zu bearbeiten sein und versehentlich einen Absturz bringen. Wenn Sie es sich bequem machen, Optionen zum Auspacken zu erzwingen, erhöhen Sie die Wahrscheinlichkeit, dass jemand in Zukunft eine Änderung vornimmt, die kompiliert, aber zur Laufzeit abstürzt.Nicht empfohlen!
if array == nil || array!.isEmpty { print("The array is nil or empty") }
Ich finde Optionen, die
array?
(optionale Verkettung) enthalten, verwirrend wie:Verwirrend?
if !(array?.isEmpty == false) { print("The array is nil or empty") } if array?.isEmpty ?? true { print("There are no objects") }
quelle
Option D: Wenn das Array nicht optional sein muss, weil es Ihnen nur wichtig ist, ob es leer ist oder nicht, initialisieren Sie es als leeres Array anstelle eines optionalen:
var array = [Int]()
Jetzt wird es immer existieren und Sie können einfach nachsehen
isEmpty
.quelle
Swift 3-4 kompatibel:
extension Optional where Wrapped: Collection { var nilIfEmpty: Optional { switch self { case .some(let collection): return collection.isEmpty ? nil : collection default: return nil } } var isNilOrEmpty: Bool { switch self { case .some(let collection): return collection.isEmpty case .none: return true } }
Verwendung:
guard let array = myObject?.array.nilIfEmpty else { return }
Oder
if myObject.array.isNilOrEmpty { // Do stuff here }
quelle
Bedingtes Auspacken:
if let anArray = array { if !anArray.isEmpty { //do something } }
EDIT: Möglich seit Swift 1.2:
if let myArray = array where !myArray.isEmpty { // do something with non empty 'myArray' }
EDIT: Möglich seit Swift 2.0:
guard let myArray = array where !myArray.isEmpty else { return } // do something with non empty 'myArray'
quelle
if array? != nil && !(array!.isEmpty) {}
array?
undarray!
in derselben Zeile stehen müssen, um ein Codegeruch zu sein? Dafür ist das bedingte Auspacken gedacht.Die elegante integrierte Lösung ist die
map
Methode von Optional . Diese Methode wird oft vergessen, macht aber genau das, was Sie hier brauchen. Sie können damit sicher eine Nachricht an das Objekt senden, das in einem optionalen Objekt verpackt ist. In diesem Fall erhalten wir eine Art Drei-Wege-Schalter: Wir könnenisEmpty
zum optionalen Array sagen und wahr, falsch oder null werden (falls das Array selbst null ist).var array : [Int]? array.map {$0.isEmpty} // nil (because `array` is nil) array = [] array.map {$0.isEmpty} // true (wrapped in an Optional) array?.append(1) array.map {$0.isEmpty} // false (wrapped in an Optional)
quelle
Anstatt zu verwenden
if
undelse
es ist besser, nur nachguard
leeren Arrays zu suchen, ohne neue Variablen für dasselbe Array zu erstellen.guard !array.isEmpty else { return } // do something with non empty ‘array’
quelle