swift - удалить или заменить <null>значений из вложенного словаря - PullRequest
0 голосов
/ 30 сентября 2019

У меня есть некоторые данные с сервера, и я использую Alamofire SwiftyJSON, чтобы преобразовать их в [String: Any]. Затем я сохраняю его в plist, используя SwiftyPlistManager. Дело в том, что при сохранении <null> произошел сбой SwiftyPlistManager, поэтому мне нужно заменить все <null> или nil на "".

Мой словарь после Alamofire SwiftyJSON выглядит следующим образом:

["info_editable": true,
 "name": Android Q,
 "is_message": true,
 "images": [["id": 92,
             "image": /media/product/102.png]],
 "video_description": <null>,
 "is_valid": true]

или это может быть -

["info_editable": true,
 "name": Android Q,
 "is_message": true,
 "images": <null>,
 "video_description": <null>,
 "is_valid": true]

Я предполагаю использовать Codable из необработанных данных, но не знаю, как установить начальное значение как пустую строку или [[]], тогдапроверьте, являются ли обработанные данные <null>, и оставьте начальное значение по умолчанию. Или есть ли способ перечислить вложенный словарь, чтобы заменить <null> на ""?

Ответы [ 3 ]

1 голос
/ 30 сентября 2019

Можно попробовать

var dic = ["1":nil,"2":"33","3":"5444"]
let res = dic.mapValues { $0 == nil ? "" : $0 }
print(res) // ["1": Optional(""), "2": Optional("33"), "3": Optional("5444")]
0 голосов
/ 01 октября 2019

Вот протоколное решение, которое рекурсивно проходит через словари и массивы:

/// Allows clients to ask the receiver to remove any `NSNull` instances
protocol NullStripable {
    func strippingNulls() -> Self
}

extension Array: NullStripable {
    func strippingNulls() -> Self {
        return compactMap {
            switch $0 {
            case let strippable as NullStripable:
                // the forced cast here is necessary as the compiler sees
                // `strippable` as NullStripable, as we casted it from `Element`
                return (strippable.strippingNulls() as! Element)
            case is NSNull:
                return nil
            default:
                return $0
            }
        }
    }
}

extension Dictionary: NullStripable {
    func strippingNulls() -> Self {
        return compactMapValues {
            switch $0 {
            case let strippable as NullStripable:
                // the forced cast here is necessary as the compiler sees
                // `strippable` as NullStripable, as we casted it from `Value`
                return (strippable.strippingNulls() as! Value)
            case is NSNull:
                return nil
            default:
                return $0
            }
        }
    }
}

Пример использования:

let dict: [String: Any] = [
    "items": ["info_editable": true,
              "name": "Android Q",
              "is_message": true,
              "images": [["id": 92,
                          "image": "/media/product/102.png"]],
              "video_description": NSNull(),
              "is_valid": true],
    "somethingElse": NSNull()
]

print(dict.strippingNulls())

Пример вывода:

["items": ["name": "Android Q", "info_editable": true, "images": [["image": "/media/product/102.png", "id": 92]], "is_message": true, "is_valid": true]]
0 голосов
/ 30 сентября 2019

на данный момент, моя лучшая идея -

1) зачеркнуть каждое значение, кроме массива словарей,

2) проверить, если строковое содержимое равно "null", затем заменить его на ""если правда.

3) массив словарей, если он содержит строку, будет иметь 2 варианта - с [[ и ]] (затем проверка каждого словаря, как указано выше) или без - в случае "images": <null>, (т. Е. <null>должен быть заменен на [[]]., но у меня около 7 запросов с разными данными, должен быть проанализирован таким странным образом, и я надеюсь найти более симпатичное решение.

...