在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 == nil
和array?.isEmpty == nil
,因此表达式array?.count == 0
和array?.isEmpty == true
都会评估为false
。
所以我试图弄清楚是否有任何方法可以通过一个条件实现这一点。
答案 0 :(得分:119)
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
,则跳过检查为空。
您可以这样做:
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)
与其使用if
和else
而不是使用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]