In Objective-C, wenn ich ein Array habe
NSArray *array;
und ich möchte überprüfen, ob es nicht leer ist, mache ich immer:
if (array.count > 0) {
NSLog(@"There are objects!");
} else {
NSLog(@"There are no objects...");
}
Auf diese Weise ist es nicht erforderlich zu prüfen, ob array == nil
der Code in den Fall else
sowie in ein Nicht-nil
-Zeichen fallen würde, ein leeres Array jedoch.
In Swift bin ich jedoch auf die Situation gestoßen, in der ich ein optionales Array habe:
var array: [Int]?
und ich kann nicht herausfinden, welche Bedingung ich verwenden soll. Ich habe einige Optionen wie:
Option A: Überprüfen Sie sowohl nicht -nil
als auch leere Fälle in derselben Bedingung:
if array != nil && array!.count > 0 {
println("There are objects")
} else {
println("No objects")
}
Option B: Entbinden Sie das Array 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 OptionBnicht sehr, da ich Code in zwei Bedingungen wiederhole. Ich bin mir jedoch nicht wirklich sicher, ob die OptionenAundCrichtig sind, oder ich sollte eine andere Methode verwenden.
Ich weiß, dass die Verwendung eines optionalen Arrays je nach Situation vermieden werden kann. In einigen Fällen kann es jedoch erforderlich sein, zu fragen, ob das Array leer ist. Ich würde gerne wissen, wie es am einfachsten geht.
@Vacawama wies darauf hin, dass diese einfache Art der Überprüfung funktioniert:
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
oder leer ist, und dann fortfahren, 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.
Wenn das Array jedoch nil
ist, fällt es nicht in den if
-Körper. Dies liegt daran, dass in diesem Fall array?.count == nil
und array?.isEmpty == nil
, also die Ausdrücke array?.count == 0
und array?.isEmpty == true
beide zu false
ausgewertet werden.
Ich versuche also herauszufinden, ob es auch nur eine Bedingung gibt, um dies zu erreichen.
Swift 3 hat die Möglichkeit zum Vergleichen von Optionals mit >
und <
entfernt, sodass einige Teile der vorherigen Antwort nicht mehr gültig sind.
Es ist immer noch möglich, Optionals mit ==
zu vergleichen. Daher können Sie am einfachsten prüfen, ob ein optionales Array Werte enthält:
if array?.isEmpty == false {
print("There are objects!")
}
Andere Möglichkeiten, wie es gemacht werden kann:
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
ist oder leer 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 dann machen, 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ßen" wird und die Überprüfung auf leer auslässt, wenn die Variable nil
ist.
Sie können einfach tun:
if array?.count > 0 {
print("There are objects")
} else {
print("No objects")
}
Wie @Martin in den Kommentaren darauf hinweist, verwendet er func ><T : _Comparable>(lhs: T?, rhs: T?) -> Bool
, was bedeutet, dass der Compiler 0
als Int?
umschließt, sodass der Vergleich mit der linken Seite erfolgen kann, die aufgrund des optionalen Verkettungsaufrufs Int?
ist.
Auf ähnliche Weise können Sie Folgendes tun:
if array?.isEmpty == false {
print("There are objects")
} else {
print("No objects")
}
Hinweis: Sie müssen hier explizit mit false
vergleichen, damit dies funktioniert.
Wenn Sie etwas tun möchten, wenn das Array nil
ist oder leer 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 dann machen, 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ßen" wird und die Überprüfung auf leer auslässt, wenn die Variable nil
ist.
Collection
* In Swift 3 geschrieben
extension Optional where Wrapped: Collection {
var isNilOrEmpty: Bool {
switch self {
case .some(let collection):
return collection.isEmpty
case .none:
return true
}
}
}
Beispielgebrauch:
if array.isNilOrEmpty {
print("The array is nil or empty")
}
Abgesehen von der obigen Erweiterung finde ich die folgende Option am deutlichsten, ohne das Erzwingen von Optionals zu erzwingen. Ich las dies als das Auspacken des optionalen Arrays und, wenn nicht vorhanden, ein leeres Array desselben Typs. Nehmen Sie dann das (nicht optionale) Ergebnis davon und führen Sie, falls es isEmpty
ist, den Bedingungscode aus.
Empfohlen
if (array ?? []).isEmpty {
print("The array is nil or empty")
}
Obwohl das Folgende klar lesbar ist, schlage ich die Gewohnheit vor, das Auspacken von Optionals nach Möglichkeit zu vermeiden. Obwohl Sie garantiert sind, dass array
niemals nil
sein wird, wenn array!.isEmpty
in diesem speziellen Fall ausgeführt wird, ist es einfach, sie später zu bearbeiten und versehentlich einen Absturz einzuführen. Wenn Sie die Option zum Auspacken von Optionen nutzen möchten, erhöhen Sie die Wahrscheinlichkeit, dass jemand in der Zukunft eine Änderung vornimmt, die kompiliert wird, jedoch 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) beinhalten, wie zum Beispiel:
Verwirrend?
if !(array?.isEmpty == false) {
print("The array is nil or empty")
}
if array?.isEmpty ?? true {
print("There are no objects")
}
Option D: Wenn das Array nicht optional sein muss, weil es Ihnen wirklich wichtig ist, ob es leer ist oder nicht, dann initialisieren Sie es als leeres Array anstelle eines optionalen:
var array = [Int]()
Jetzt wird es immer existieren und Sie können einfach nach isEmpty
suchen.
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
}
}
Verwendungszweck:
guard let array = myObject?.array.nilIfEmpty else { return }
Oder
if myObject.array.isNilOrEmpty {
// Do stuff here
}
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'
Anstelle von if
und else
ist es besser, guard
zu verwenden, um nach leeren Arrays zu suchen, ohne neue Variablen für dasselbe Array zu erstellen.
guard !array.isEmpty else {
return
}
// do something with non empty ‘array’
Die elegante integrierte Lösung ist die map
-Methode von Optional. Diese Methode wird oft vergessen, macht aber genau das, was Sie hier brauchen. Damit können Sie eine Nachricht sicher an das in einem optionalen Gerät verpackte Objekt senden. Wir erhalten in diesem Fall eine Art Dreifach-Switch: Wir können isEmpty
zum optionalen Array sagen und erhalten true, false oder nil (falls das Array selbst gleich 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)