Проверьте, если массив пуст
в 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]?
и я не в состоянии чтобы выяснить, какое условие использовать. У меня есть несколько вариантов, например:
В: проверьте оба не -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 правильно или я должен использовать любой другой способ сделать это.
я знаю, что использование дополнительного массива можно было бы избежать в зависимости от ситуации, но в некоторых случаях может потребоваться спросить, пуст ли он. Поэтому я хотел бы знать, как это сделать самым простым способом.
EDIT:
как отметил @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.
поэтому я пытаюсь выяснить, есть ли какой-либо способ достичь этого только с одним условием.
7 ответов:
обновленный ответ для Swift 3:
Swift 3 убрал возможность сравнивать опционные с
>и<, таким образом, некоторые части предыдущего ответа больше не действительны.по-прежнему можно сравнить optionals с
==, поэтому самый простой способ проверить, содержит ли необязательный массив значения: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 вариантов:В:
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 точно захватывает, как вы описали его на английском языке: я бы рекомендовал вам использовать это так легко понять. В этом нет ничего плохого, тем более, что это будет "короткое замыкание" и пропустить проверку на пустоту, если переменная
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 вариантов:А:
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 точно захватывает, как вы описали его на английском языке:"я хочу что-то сделать специальные только тогда, когда он равен нулю или пуст." я бы рекомендовал вам использовать это так легко понять. В этом нет ничего плохого, тем более, что это будет "короткое замыкание" и пропустить проверку на пустоту, если переменная
nil.
Вариант D: если массив не должен быть необязательным, потому что вам действительно важно, пуст он или нет, инициализируйте его как пустой массив вместо необязательного:
var array = [Int]()теперь он всегда будет существовать, и вы можете просто проверить
isEmpty.
свойство расширения на
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") }Другие Функции
кроме расширения выше, я нахожу следующий вариант наиболее ясным без принудительного разворачивания optionals. Я прочитал это как разворачивание необязательного массива и если 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") }
условных разверток:
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'
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 }
элегантный встроенное решение не является обязательным по
mapметод. Этот метод часто забывается, но он делает именно то, что вам нужно здесь; он позволяет отправлять сообщение на вещь, завернутую внутри опционально, безопасно. В этом случае мы получаем своего рода трехходовой переключатель: мы можем сказатьisEmptyк необязательному массиву и получить true, false или nil (в случае, если массив сам по себе nil).var array : [Int]? array.map {.isEmpty} // nil (because `array` is nil) array = [] array.map {.isEmpty} // true (wrapped in an Optional) array?.append(1) array.map {.isEmpty} // false (wrapped in an Optional)
вместо
ifиelseэто лучший способ, чтобы просто использоватьguardдля проверки пустого массива без создания новых переменных для того же массива.guard !array.isEmpty else { return } // do something with non empty ‘array’
Comments