【问题标题】:swift - delete or replace <null> values from nested dictionaryswift - 从嵌套字典中删除或替换 <null> 值
【发布时间】:2019-09-30 13:29:45
【问题描述】:

我有一些来自服务器的数据,我正在使用Alamofire SwiftyJSON 将其转换为[String: Any]。然后我使用SwiftyPlistManager 将其保存到 plist。重点是SwiftyPlistManager在保存&lt;null&gt;的时候崩溃了,所以我需要把&lt;null&gt;或者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,但不知道如何将初始值设置为空字符串或[[]],然后检查parced数据是否为&lt;null&gt;并将初始值保留为默认值。 或者有没有办法列出嵌套字典来替换&lt;null&gt;to ""

【问题讨论】:

  • var updatedDictionary = Dictionary(uniqueKeysWithValues: yourDictionary.map { ($0, $1 != nil ? $1! : "") })

标签: swift swifty-json codable


【解决方案1】:

你可以试试

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")]

【讨论】:

    【解决方案2】:

    目前,我最好的想法是 -

    1) 字符串化除字典数组之外的每个值,

    2) 检查字符串内容是否为“null”,然后将其替换为""如果为真。

    3) 字典数组,如果字符串化,将有 2 个选项 - 使用 [[]](然后像上面一样检查每个字典)或不使用 - 如果是 "images": &lt;null&gt;,(所以 &lt;null&gt; 应该被替换与[[]]。 但是我有大约 7 个不同数据的请求,应该以这种奇怪的方式解析,我希望找到更漂亮的决定。

    【讨论】:

      【解决方案3】:

      这是一个协议解决方案,它递归地通过字典和数组:

      /// 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]]
      

      【讨论】:

        【解决方案4】:

        试试这个。它将删除 null 并替换为空白字符串,而不会丢失密钥。

        func removeNullFromResponse(response:NSDictionary) -> NSDictionary{
            
            let blankString = "\"\""
            let myMutableDict: NSMutableDictionary = NSMutableDictionary(dictionary: response)
        
            var data = try? JSONSerialization.data(withJSONObject:myMutableDict, options: JSONSerialization.WritingOptions.prettyPrinted)
        
            var strData = NSString.init(data: data!, encoding:String.Encoding.utf8.rawValue)
            strData = strData?.replacingOccurrences(of: "<NULL>", with: blankString) as NSString?
            strData = strData?.replacingOccurrences(of: "<null>", with: blankString) as NSString?
            strData = strData?.replacingOccurrences(of: "<Null>", with: blankString) as NSString?
            strData = strData?.replacingOccurrences(of: "NULL", with: blankString) as NSString?
            strData = strData?.replacingOccurrences(of: "null", with: blankString) as NSString?
            
            data = strData?.data(using: String.Encoding.utf8.rawValue)!
            
            var dictionary = NSDictionary()
            
            do
            {
                dictionary = try JSONSerialization.jsonObject(with: data! , options: JSONSerialization.ReadingOptions()) as! NSDictionary
                
            } catch {
                print(error)
            }
            
            return dictionary as NSDictionary
        }
        

        【讨论】:

        • 这是一个非常不切实际的解决方案。如果任何值包含替换对象怎么办,例如Vanilla 包含 nil,该值将被替换为空白字符串并返回错误。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-03-08
        • 2019-09-06
        • 2018-04-14
        • 2019-09-08
        • 1970-01-01
        相关资源
        最近更新 更多