检查可选数组是否为空

时间:2014-12-21 11:34:07

标签: ios arrays swift

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

NSArray *array;

我想检查它是否为空,我总是这样做:

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

这样,就不需要检查是否array == nil,因为这种情况会导致代码落入else情况,以及非nil但是空数组会做的。

然而,在Swift中,我偶然发现了我有一个可选数组的情况:

var array: [Int]?

我无法确定使用哪种条件。我有一些选择,比如:

选项A:检查同一条件下的非nil和空案例:

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

选项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...")
}

选项C:使用Swift提供的合并运算符:

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

我不太喜欢 B 选项,因为我在两个条件下重复代码。但我不确定选项 A C 是否正确,或者我应该使用其他任何方式来执行此操作。

我知道根据具体情况可以避免使用可选数组,但在某些情况下可能需要询问它是否为空。所以我想知道最简单的方法是什么。

<小时/> 修改

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

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

但是,我正在尝试这样一种情况,即只有在nil或空时才想做一些特殊的事情,然后继续,无论数组是否有元素。所以我试过了:

if array?.count == 0 {
    println("There are no objects")
}

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

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

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

但是,当数组为nil时,它不会落入if主体。这是因为,在这种情况下,array?.count == nilarray?.isEmpty == nil,因此表达式array?.count == 0array?.isEmpty == true都会评估为false

所以我试图弄清楚是否有任何方法可以通过一个条件实现这一点。

8 个答案:

答案 0 :(得分:119)

更新了Swift 3及以上版本的答案:

Swift 3删除了将选项与><进行比较的功能,因此上一个答案的某些部分不再有效。

仍然可以将选项与==进行比较,因此检查可选数组是否包含值的最直接方法是:

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

可以采取的其他方式:

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

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

选项A:

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

选项B:

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

选项C:

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

选项D:

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

选项E:

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

选项F:

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

选项C 完全捕捉到您用英语描述的方式:&#34;我想只在零或空时做一些特别的事情。&#34; 我建议您使用它,因为它很容易理解。这没有什么不妥,特别是因为它会短路&#34;如果变量为nil,则跳过检查为空。



Swift 2.x的先前答案:

您可以这样做:

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

正如@Martin在评论中指出的那样,它使用func ><T : _Comparable>(lhs: T?, rhs: T?) -> Bool,这意味着编译器将0包装为Int?,以便可以与左侧进行比较。由于可选的链接调用,因此是Int?

以类似的方式,您可以这样做:

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

注意:您必须明确地与false进行比较才能实现此目的。


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

选项A:

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

选项B:

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

选项C:

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

选项D:

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

选项E:

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

选项F:

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

选项G:

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

选项D 完全捕捉到您用英语描述的方式:&#34;我想只在零或空时做一些特别的事情。&#34; 我建议您使用它,因为它很容易理解。这没有什么不妥,特别是因为它会短路&#34;如果变量为nil,则跳过检查为空。

答案 1 :(得分:7)

Collection协议

上的扩展属性

*用Swift 3编写

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

使用示例:

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

其他选项

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

<强>推荐

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

虽然以下内容清楚地表明,但我建议尽可能避免使用力量展开选项。虽然在这种特定情况下执行array时保证nil永远不会array!.isEmpty,但以后编辑它会很容易,并且无意中会引发崩溃。当你成为舒适的力量展开选项时,你会增加某人在未来进行更改但在运行时崩溃但崩溃的可能性。

不推荐!

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

我发现包含array?(可选链接)的选项令人困惑,例如:

<强>易混吗

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

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

答案 2 :(得分:5)

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

var array = [Int]()

现在它将永远存在,您只需检查isEmpty即可。

答案 3 :(得分:4)

与Swift 3-4兼容:

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

用法:

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

if myObject.array.isNilOrEmpty {
    // Do stuff here
}

答案 4 :(得分:3)

有条件的解包:

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

编辑:从Swift 1.2开始可能:

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

编辑:自Swift 2.0以来可能:

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

答案 5 :(得分:0)

优雅的内置解决方案是Optional的map方法。这种方法通常被遗忘,但是它确实可以满足您的需要。它使您可以安全地向包裹在Optional内的东西发送消息。在这种情况下,我们以一种三向切换结束:我们可以对可选数组说isEmpty,并得到true,false或nil(如果数组本身为nil)。

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)

答案 6 :(得分:0)

与其使用ifelse而不是使用guard来检查空数组,而不用为同一数组创建新变量,则是更好的方法。

guard !array.isEmpty else {
    return
}
// do something with non empty ‘array’

答案 7 :(得分:0)

最好使用 if 来检查空数组。为什么是 bcoz,例如,如果我们试图在列表数组中找到最大的整数,显然我们会将 list[0] 与列表中的每个整数进行比较。当时它给了我们索引超出范围的异常......你可以同时使用 IF 和 Guard

func findGreatestInList(list: [Int]?)-> Int? {
        if list!.count == 0 {
            print("List is empty")
            return nil
           
       }
       /*guard list!.isEmpty else {
            print("List is empty")
            return nil
        }*/
        var greatestValue = list![0]
            for number in 0...list!.count-1 {
            
              if list![number] > greatestValue {
                greatestValue = list![number]