Проверьте, если массив пуст



в 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.



поэтому я пытаюсь выяснить, есть ли какой-либо способ достичь этого только с одним условием.

1006   7  

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

    Ничего не найдено.