Check for an extra array

In Objective-C, when I have an array

NSArray *array; 

and I want to check if it is empty, I always do:

 if (array.count > 0) { NSLog(@"There are objects!"); } else { NSLog(@"There are no objects..."); } 

Thus, there is no need to check if array == nil , since this situation will cause the code to fall into the else case, and also not nil , but an empty array will do.

However, in Swift, I came across a situation in which I have an extra array:

 var array: [Int]? 

and I can’t figure out which condition to use. I have several options, for example:

Option A: Check both non nil and empty cases in the same state:

 if array != nil && array!.count > 0 { println("There are objects") } else { println("No objects") } 

Option B: Untie the array using 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: Using the coalescence operator that Swift provides:

 if (array?.count ?? 0) > 0 { println("There are objects") } else { println("No objects") } 

I don't like option B because I repeat the code in two conditions. But I'm not sure if options A and C are correct, or should I use any other way to do this.

I know that using an optional array could be avoided depending on the situation, but in some cases you might need to ask if it is empty. So I would like to know how to do this in the easiest way.




EDIT:

As @vacawama noted, this simple way of checking:

 if array?.count > 0 { println("There are objects") } else { println("No objects") } 

However, I tried to use the case where I want to do something special only when it is nil or empty, and then continue regardless of whether the array has elements or not. So I tried:

 if array?.count == 0 { println("There are no objects") } // Do something regardless whether the array has elements or not. 

As well as

 if array?.isEmpty == true { println("There are no objects") } // Do something regardless whether the array has elements or not. 

But, when the array is nil , it does not fall into the body of the if . And this is because in this case array?.count == nil and array?.isEmpty == nil , therefore the expressions array?.count == 0 and array?.isEmpty == true are evaluated as false .

So, I'm trying to figure out if there is a way to achieve this with only one condition.

+55
arrays ios swift
Dec 21 '14 at 11:34
source share
7 answers

Updated answer for Swift 3 and above:

Swift 3 removed the ability to compare options with > and < , so some parts of the previous answer are no longer valid.

It is still possible to compare optional values ​​with == , so the easiest way to check if an optional array contains values ​​is:

 if array?.isEmpty == false { print("There are objects!") } 

Other ways to do this:

 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!") } 



If you want to do something when the array is nil or empty, you have at least 6 options:

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 accurately reflects how you described it in English: "I want to do something special only when it's empty or zero." I would recommend you use this as it is easy to understand. There is nothing wrong with that, especially since it will “short-circuit” and skip the check for void if the variable is nil .







Previous answer for Swift 2.x:

You can simply do:

 if array?.count > 0 { print("There are objects") } else { print("No objects") } 

As @Martin points out in the comments, it uses func ><T: _Comparable>(lhs: T?, rhs: T?) → Bool which means that the compiler wraps 0 as an Int? so that a comparison can be made on the left side, which is Int? due to an optional call chain.

Similarly, you can do:

 if array?.isEmpty == false { print("There are objects") } else { print("No objects") } 

Note: you must explicitly compare with false here for this to work.




If you want to do something when the array is nil or empty, you have at least 7 options:

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 accurately reflects how you described it in English: "I want to do something special only when it's empty or zero." I would recommend you use this as it is easy to understand. There is nothing wrong with that, especially since it will “short-circuit” and skip the check for void if the variable is nil .

+118
Dec 21 '14 at 11:39
source share

Extension property in Collection protocol

* Written in Swift 3

 extension Optional where Wrapped: Collection { var isNilOrEmpty: Bool { switch self { case .some(let collection): return collection.isEmpty case .none: return true } } } 

Usage example:

 if array.isNilOrEmpty { print("The array is nil or empty") } 

Other options

In addition to the above expansion, I believe that the next option is most clear without the possibility of a deployment of force. I read this as expanding an optional array, and if nil, replacing an empty array of the same type. Then, having received (not optional) the result of this, and if it isEmpty will execute the conditional code.

Recommended

 if (array ?? []).isEmpty { print("The array is nil or empty") } 

Although the following is clearly readable, I suggest the habit of avoiding the possibility of unfolding strength when possible. Although you are guaranteed that array will never be nil when array!.isEmpty is executed in this particular case, it would be easy to edit it later and inadvertently crash. When you become comfortable deploying additional features, you increase the likelihood that someone will make future changes that compile but fail at runtime.

Not recommended!

 if array == nil || array!.isEmpty { print("The array is nil or empty") } 

Am I finding options that include an array? (optional chain) confusing, for example:

Incomprehensible?

 if !(array?.isEmpty == false) { print("The array is nil or empty") } if array?.isEmpty ?? true { print("There are no objects") } 
+7
Jan 26 '17 at 6:40
source share

Option D: If the array does not have to be optional, because you really need it only if it is empty or not, initialize it as an empty array instead of optional:

 var array = [Int]() 

Now it will always exist, and you can just check isEmpty .

+5
Dec 21 '14 at 11:55
source share

Swift 3-4 is compatible:

 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 } } 

Application:

 guard let array = myObject?.array.nilIfEmpty else { return } 

Or

 if myObject.array.isNilOrEmpty { // Do stuff here } 
+4
Jul 18 '18 at 10:59
source share

Conditional scan:

 if let anArray = array { if !anArray.isEmpty { //do something } } 

EDIT: possible since Swift 1.2:

 if let myArray = array where !myArray.isEmpty { // do something with non empty 'myArray' } 

EDIT: possible since Swift 2.0:

 guard let myArray = array where !myArray.isEmpty else { return } // do something with non empty 'myArray' 
+3
Dec 21 '14 at 11:44
source share

An elegant embedded solution is an additional way to map . This method is often overlooked, but it does exactly what you need here; it allows you to safely send a message to an item wrapped in optional. In this case, we get a kind of threeway switch: we can say isEmpty for an optional array and get true, false or nil (in case the array itself is zero).

 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) 
0
Jul 18 '18 at 11:17
source share

Instead of using if and else it is best to use guard to check for an empty array without creating new variables for the same array.

 guard !array.isEmpty else { return } // do something with non empty 'array 
0
07 Sep '18 at 9:42
source share



All Articles