检查可选数组是否为空

时间:2021-03-18 11:09:04

In Objective-C, when I have an array

在Objective-C中,当我有一个数组

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.

这样,就不需要检查array = nil,因为这种情况会导致代码陷入else情况,也不需要检查非nil但空的数组。

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

然而,在Swift中,我遇到了我有一个可选数组的情况:

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:

选项A:在相同的条件下,检查非nil和空的情况:

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

Option B: Unbind the array using let:

选项B:使用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:

选项C:使用Swift提供的合并操作符:

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.

我不太喜欢选项B,因为我在两种情况下重复代码。但是我不确定选项A和C是正确的还是我应该用其他方法来做。

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:

正如@vacawama指出的,这种简单的检查方法是有效的:

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:

然而,我正在尝试这样一种情况:我只想在nil或空的时候做一些特殊的事情,然后不管数组是否有元素都继续。所以我试着:

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.

但是,当数组为nil时,它不属于if主体。这是因为,在这种情况下,数组?count == nil和数组?。isEmpty == nil,表达式数组?count == = 0,数组?。isEmpty == = true都被赋值为false。

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

所以我想知道是否有任何方法可以达到这个目的只有一个条件。

4 个解决方案

#1


108  

Updated answer for Swift 3:

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

Swift 3已经取消了将选项与>和 <进行比较的能力,因此前一个答案的某些部分不再有效。< p>

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:

如果你想在数组为nil或空的时候做某事,你至少有6个选择:

Option A:

选项一:

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

Option B:

选项B:

if array == nil || array!.count == 0 {
    print("There are no objects")
}

Option C:

选择C:

if array == nil || array!.isEmpty {
    print("There are no objects")
}

Option D:

选择D:

if (array ?? []).isEmpty {
    print("There are no objects")
}

Option E:

选择E:

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

Option F:

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.

选项C准确地描述了你用英语描述它的方式:“我想做一些特殊的事情,只有当它是nil或空的时候。”我建议您使用它,因为它很容易理解。这没有什么错,特别是因为它将“短路”,如果变量为nil,则跳过检查为empty。



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.

正如@Martin在评论中指出的,它使用func > (lhs: T?-> Bool这意味着编译器将0包装成Int型?这样我们就可以比较左手边的Int数了?因为可选的链接调用。

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.

注意:您必须在这里显式地与false进行比较才能使其工作。


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

如果你想在数组为nil或为空时做点什么,你至少有7个选择:

Option A:

选项一:

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

Option B:

选项B:

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

Option C:

选择C:

if array == nil || array!.count == 0 {
    print("There are no objects")
}

Option D:

选择D:

if array == nil || array!.isEmpty {
    print("There are no objects")
}

Option E:

选择E:

if (array ?? []).isEmpty {
    print("There are no objects")
}

Option F:

F选项:

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

Option G:

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.

选项D准确地描述了你用英语描述它的方式:“我想做一些特殊的事情,只有当它是nil或空的时候。”我建议您使用它,因为它很容易理解。这没有什么错,特别是因为它将“短路”,如果变量为nil,则跳过检查为empty。

#2


5  

Option D: If the array doesn't need to be optional, because you only really care if it's empty or not, initialise it as an empty array instead of an optional:

选项D:如果数组不需要是可选的,因为您只关心它是否为空,那么将它初始化为空数组而不是可选的:

var array = [Int]()

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

现在它将永远存在,并且您可以简单地检查是否为空。

#3


3  

Extension Property on the Collection Protocol

*Written in Swift 3

*斯威夫特写的3

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

Example Use:

使用示例:

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

 

 

Other Options

Other than the extension above, I find the following option most clear without force unwrapping optionals. I read this as unwrapping the optional array and if nil, substituting an empty array of the same type. Then, taking the (non-optional) result of that and if it isEmpty execute the conditional code.

除了上面的扩展之外,我发现以下选项是最清晰的,没有强制展开选项。我将其解读为解包可选数组和if nil,替换相同类型的空数组。然后,获取(非可选的)结果,如果结果为空,则执行条件代码。

Recommended

推荐

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

Though the following reads clearly, I suggest a habit of avoiding force unwrapping optionals whenever possible. Though you are guaranteed that array will never be nil when array!.isEmpty is executed in this specific case, it would be easy to edit it later and inadvertently introduce a crash. When you become comfortable force unwrapping optionals, you increase the chance that someone will make a change in the future that compiles but crashes at runtime.

尽管下面的内容读起来很清楚,但我建议在任何可能的情况下避免强制打开选项。虽然你可以保证数组永远不会是nil !isEmpty是在这个特定的情况下执行的,稍后很容易对它进行编辑,并在不经意间导致了崩溃。当您能够轻松地强制展开选项时,您就增加了将来有人进行编译但在运行时崩溃的可能性。

Not Recommended!

不推荐!

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

I find options that include array? (optional chaining) confusing such as:

找到包含数组的选项?(可选链接)混淆如:

Confusing?

困惑吗?

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

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

#4


2  

Conditional unwrapping:

条件展开:

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

EDIT: Possible since Swift 1.2:

编辑:可能,因为Swift 1.2:

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

EDIT: Possible since Swift 2.0:

编辑:可能因为Swift 2.0:

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

#1


108  

Updated answer for Swift 3:

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

Swift 3已经取消了将选项与>和 <进行比较的能力,因此前一个答案的某些部分不再有效。< p>

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:

如果你想在数组为nil或空的时候做某事,你至少有6个选择:

Option A:

选项一:

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

Option B:

选项B:

if array == nil || array!.count == 0 {
    print("There are no objects")
}

Option C:

选择C:

if array == nil || array!.isEmpty {
    print("There are no objects")
}

Option D:

选择D:

if (array ?? []).isEmpty {
    print("There are no objects")
}

Option E:

选择E:

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

Option F:

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.

选项C准确地描述了你用英语描述它的方式:“我想做一些特殊的事情,只有当它是nil或空的时候。”我建议您使用它,因为它很容易理解。这没有什么错,特别是因为它将“短路”,如果变量为nil,则跳过检查为empty。



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.

正如@Martin在评论中指出的,它使用func > (lhs: T?-> Bool这意味着编译器将0包装成Int型?这样我们就可以比较左手边的Int数了?因为可选的链接调用。

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.

注意:您必须在这里显式地与false进行比较才能使其工作。


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

如果你想在数组为nil或为空时做点什么,你至少有7个选择:

Option A:

选项一:

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

Option B:

选项B:

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

Option C:

选择C:

if array == nil || array!.count == 0 {
    print("There are no objects")
}

Option D:

选择D:

if array == nil || array!.isEmpty {
    print("There are no objects")
}

Option E:

选择E:

if (array ?? []).isEmpty {
    print("There are no objects")
}

Option F:

F选项:

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

Option G:

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.

选项D准确地描述了你用英语描述它的方式:“我想做一些特殊的事情,只有当它是nil或空的时候。”我建议您使用它,因为它很容易理解。这没有什么错,特别是因为它将“短路”,如果变量为nil,则跳过检查为empty。

#2


5  

Option D: If the array doesn't need to be optional, because you only really care if it's empty or not, initialise it as an empty array instead of an optional:

选项D:如果数组不需要是可选的,因为您只关心它是否为空,那么将它初始化为空数组而不是可选的:

var array = [Int]()

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

现在它将永远存在,并且您可以简单地检查是否为空。

#3


3  

Extension Property on the Collection Protocol

*Written in Swift 3

*斯威夫特写的3

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

Example Use:

使用示例:

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

 

 

Other Options

Other than the extension above, I find the following option most clear without force unwrapping optionals. I read this as unwrapping the optional array and if nil, substituting an empty array of the same type. Then, taking the (non-optional) result of that and if it isEmpty execute the conditional code.

除了上面的扩展之外,我发现以下选项是最清晰的,没有强制展开选项。我将其解读为解包可选数组和if nil,替换相同类型的空数组。然后,获取(非可选的)结果,如果结果为空,则执行条件代码。

Recommended

推荐

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

Though the following reads clearly, I suggest a habit of avoiding force unwrapping optionals whenever possible. Though you are guaranteed that array will never be nil when array!.isEmpty is executed in this specific case, it would be easy to edit it later and inadvertently introduce a crash. When you become comfortable force unwrapping optionals, you increase the chance that someone will make a change in the future that compiles but crashes at runtime.

尽管下面的内容读起来很清楚,但我建议在任何可能的情况下避免强制打开选项。虽然你可以保证数组永远不会是nil !isEmpty是在这个特定的情况下执行的,稍后很容易对它进行编辑,并在不经意间导致了崩溃。当您能够轻松地强制展开选项时,您就增加了将来有人进行编译但在运行时崩溃的可能性。

Not Recommended!

不推荐!

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

I find options that include array? (optional chaining) confusing such as:

找到包含数组的选项?(可选链接)混淆如:

Confusing?

困惑吗?

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

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

#4


2  

Conditional unwrapping:

条件展开:

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

EDIT: Possible since Swift 1.2:

编辑:可能,因为Swift 1.2:

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

EDIT: Possible since Swift 2.0:

编辑:可能因为Swift 2.0:

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