Подтвердить что ты не робот

Как удалить все элементы nil в массиве Swift?

Основной способ не работает.

for index in 0 ..< list.count {
    if list[index] == nil {
        list.removeAtIndex(index) //this will cause array index out of range
    }
}
4b9b3361

Ответ 1

Проблема с вашим кодом в том, что 0..< list.count выполняется один раз в начале цикла, когда list все еще содержит все свои элементы. Каждый раз, когда вы удаляете один элемент, list.count уменьшается, но диапазон итераций не изменяется. Вы заканчиваете тем, что читаете слишком далеко.

В Swift 4.1 и выше вы можете использовать compactMap чтобы отбросить nil элементов последовательности. compactMap возвращает массив необязательных значений.

let list: [Foo?] = ...
let nonNilElements = list.compactMap { $0 }

Если вам все еще нужен массив опций, вы можете использовать filter для удаления nil элементов:

list = list.filter { $0 != nil }

Ответ 2

В Swift 2.0 вы можете использовать flatMap:

list.flatMap { $0 }

Ответ 3

Теперь в Swift 4.2 вы можете использовать

list.compactMap{ $0 }
  • list.flatMap {$ 0} уже устарел.

Ответ 4

В Swift 4.2:

//MARK:- Remove null value

func removeNSNull(_ data: Any) -> Any {

    if data is NSArray {
        let tempMain = (data as! NSArray).mutableCopy() as! NSMutableArray
        for dict in tempMain {
            if dict is NSNull {
                let Index = tempMain.index(of: dict)
                tempMain.replaceObject(at: Index, with: "")
            }else if dict is NSDictionary {
                let mutableOutDict = removeNSNull(dict)
                let Index = tempMain.index(of: dict)
                tempMain.replaceObject(at: Index, with: mutableOutDict)
            }else if dict is String && (dict as! String == "<null>") {
                let Index = tempMain.index(of: dict)
                tempMain.replaceObject(at: Index, with: "")
            }else if (dict is NSArray) && (dict as! NSArray).count > 0 {
                let tempSub = removeNSNull(dict)
                let Index = tempMain.index(of: dict)
                tempMain.replaceObject(at: Index, with: tempSub)
            }
        }
        return tempMain.mutableCopy() as! NSArray

    }else if data is NSDictionary {
        let mutableDict = (data as! NSDictionary).mutableCopy() as! NSMutableDictionary
        for (key, value) in mutableDict {
            if value is NSNull {
                mutableDict.setValue("", forKey: key as! String)
            }else if value is String && (value as! String == "<null>") {
                mutableDict.setValue("", forKey: key as! String)
            }else if (value is NSArray) && (value as! NSArray).count > 0 {
                let array = removeNSNull(value)
                mutableDict.setValue(array, forKey: key as! String)
            }else if (value is NSDictionary){
                let dict = removeNSNull(value)
                mutableDict.setValue(dict, forKey: key as! String)
            }
        }
        return mutableDict.mutableCopy() as! NSDictionary
    }else {
        return ""
    }
}