Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
175 views
in Technique[技术] by (71.8m points)

ios - Check if optional array is empty

In Objective-C, when I have an array

NSArray *array;

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

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

That way, there is no need to check if array == nil since this situation will lead the code to fall into the else case, as well as a non-nil but empty array would do.

However, in Swift, I have stumbled across the situation in which I have an optional array:

var array: [Int]?

and I am not being able to figure out which condition to use. I have some options, like:

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

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

Option B: Unbind 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 coalescing operator that Swift provides:

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

I do not like the option B very much, because I am repeating code in two conditions. But I am not really sure about whether options A and C are correct or I should use any other way of doing this.

I know that the use of an optional array could be avoided depending on the situation, but in some case it could be necessary to ask if it is empty. So I would like to know what is the way to do it the simplest way.


EDIT:

As @vacawama pointed out, this simple way of checking it works:

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

However, I was trying the case in which I want to do something special only when it is nil or empty, and then continue regardless 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.

And also

if array?.isEmpty == true {
    println("There are no objects")
}

// Do something regardless whether the array has elements or not.

But, when array is nil, it does not fall into the if body. And this is because, in that case, array?.count == nil and array?.isEmpty == nil, so the expressions array?.count == 0 and array?.isEmpty == true both evaluate to false.

So I am trying to figure out if there is any way of achieve this with just one condition as well.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Updated answer for Swift 3 and above:

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

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

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

Other ways it can be done:

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 is empty, you have at least 6 choices:

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 exactly captures how you described it in English: "I want to do something special only when it is nil or empty." I would recommend that you use this since it is easy to understand. There is nothing wrong with this, especially since it will "short circuit" and skip the check for empty 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 the comparison can be made with the left hand side which is an Int? because of the optional chaining call.

In a similar way, you could do:

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

Note: You have to explicitly compare with false here for this to work.


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

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


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...