【问题标题】:Dynamically remove null value from swift dictionary using function使用函数从快速字典中动态删除空值
【发布时间】:2021-02-10 07:01:25
【问题描述】:

我有以下字典代码

var dic : [String: AnyObject] = ["FirstName": "Anvar", "LastName": "Azizov", "Website": NSNull(),"About": NSNull()]

我已经使用下面的代码删除了具有空值的键

var keys = dic.keys.array.filter({dic[$0] is NSNull})
for key in keys {
  dic.removeValueForKey(key)
}

它适用于静态字典,但我想动态地做,我想用函数来做,但是每当我将字典作为参数传递时,它都作为 let 表示常量,所以不能删除空键 我为此编写了以下代码

func nullKeyRemoval(dic : [String: AnyObject]) -> [String: AnyObject]{
        var keysToRemove = dic.keys.array.filter({dic[$0] is NSNull})
        for key in keysToRemove {
            dic.removeValueForKey(key)
        }
        return dic
}

请告诉我解决方法

【问题讨论】:

  • func nullKeyRemoval(var dic : [String: AnyObject]) -> [String: AnyObject]{
  • 为什么你不在过滤函数中改变你的条件,这样你就可以得到包含你想要的数据的数组并且你不需要再次枚举它:({!(dic[$0]是 NSNull)})

标签: ios swift


【解决方案1】:

与其使用全局函数(或方法),不如使用扩展使其成为Dictionary 的方法?

extension Dictionary {
    func nullKeyRemoval() -> Dictionary {
        var dict = self

        let keysToRemove = Array(dict.keys).filter { dict[$0] is NSNull }
        for key in keysToRemove {
            dict.removeValue(forKey: key)
        }

        return dict
    }
}

它适用于任何泛型类型(因此不限于String, AnyObject),您可以直接从字典本身调用它:

var dic : [String: AnyObject] = ["FirstName": "Anvar", "LastName": "Azizov", "Website": NSNull(),"About": NSNull()]
let dicWithoutNulls = dic.nullKeyRemoval()

【讨论】:

    【解决方案2】:

    Swift 5 添加了compactMapValues(_:),这会让你这样做

    let filteredDict = dict.compactMapValues { $0 is NSNull ? nil : $0 }
    

    【讨论】:

      【解决方案3】:

      对于Swift 3.0 / 3.1,这可能会有所帮助。同时删除NSNull对象递归:

      extension Dictionary {
          func nullKeyRemoval() -> [AnyHashable: Any] {
              var dict: [AnyHashable: Any] = self
      
              let keysToRemove = dict.keys.filter { dict[$0] is NSNull }
              let keysToCheck = dict.keys.filter({ dict[$0] is Dictionary })
              for key in keysToRemove {
                  dict.removeValue(forKey: key)
              }
              for key in keysToCheck {
                  if let valueDict = dict[key] as? [AnyHashable: Any] {
                      dict.updateValue(valueDict.nullKeyRemoval(), forKey: key)
                  }
              }
              return dict
          }
      }
      

      【讨论】:

      • 工作,但仅适用于不包含嵌入式数组的嵌入式字典
      【解决方案4】:

      Swift 3+:从字典中删除 null

       func removeNSNull(from dict: [String: Any]) -> [String: Any] {
          var mutableDict = dict
          let keysWithEmptString = dict.filter { $0.1 is NSNull }.map { $0.0 }
          for key in keysWithEmptString {
              mutableDict[key] = ""
          }
          return mutableDict
      }
      

      使用

      let outputDict = removeNSNull(from: ["name": "Foo", "address": NSNull(), "id": "12"])
      

      输出:[“name”:“Foo”,“address”:“”,“id”:“12”]

      【讨论】:

        【解决方案5】:

        斯威夫特 4

        比其他解决方案更有效率。仅使用 O(n) 复杂度。

        extension Dictionary where Key == String, Value == Any? {
        
            var trimmingNullValues: [String: Any] {
                var copy = self
                forEach { (key, value) in
                    if value == nil {
                        copy.removeValue(forKey: key)
                    }
                }
                return copy as [Key: ImplicitlyUnwrappedOptional<Value>]
            }
        }
        

        Usage: ["ok": nil, "now": "k", "foo": nil].trimmingNullValues // = ["now": "k"]

        如果您的字典是可变的,您可以就地执行此操作并防止低效复制:

        extension Dictionary where Key == String, Value == Any? {
            mutating func trimNullValues() {
                forEach { (key, value) in
                    if value == nil {
                        removeValue(forKey: key)
                    }
                }            
            }
        }
        

        Usage: var dict: [String: Any?] = ["ok": nil, "now": "k", "foo": nil] dict.trimNullValues() // dict now: = ["now": "k"]

        【讨论】:

          【解决方案6】:

          最简洁的方法,只需 1 行

          extension Dictionary {
              func filterNil() -> Dictionary {
                  return self.filter { !($0.value is NSNull) }
              }
          }
          

          【讨论】:

            【解决方案7】:

            支持嵌套NSNull

            要删除任何嵌套级别(包括数组字典)中的任何NSNull外观,请尝试以下操作:

            extension Dictionary where Key == String {
                func removeNullsFromDictionary() -> Self {
                    var destination = Self()
                    for key in self.keys {
                        guard !(self[key] is NSNull) else { destination[key] = nil; continue }
                        guard !(self[key] is Self) else { destination[key] = (self[key] as! Self).removeNullsFromDictionary() as? Value; continue }
                        guard self[key] is [Value] else { destination[key] = self[key]; continue }
            
                        let orgArray = self[key] as! [Value]
                        var destArray: [Value] = []
                        for item in orgArray {
                            guard let this = item as? Self else { destArray.append(item); continue }
                            destArray.append(this.removeNullsFromDictionary() as! Value)
                        }
                        destination[key] = destArray as? Value
                    }
                    return destination
                }
            }
            

            【讨论】:

              【解决方案8】:

              与其使用全局函数(或方法),不如使用扩展使其成为 Dictionary 的方法?

                 extension NSDictionary
                  {
                      func RemoveNullValueFromDic()-> NSDictionary
                      {
                          let mutableDictionary:NSMutableDictionary = NSMutableDictionary(dictionary: self)
                          for key in mutableDictionary.allKeys
                          {
                              if("\(mutableDictionary.objectForKey("\(key)")!)" == "<null>")
                              {
                                  mutableDictionary.setValue("", forKey: key as! String)
                              }
                              else if(mutableDictionary.objectForKey("\(key)")!.isKindOfClass(NSNull))
                              {
                                  mutableDictionary.setValue("", forKey: key as! String)
                              }
                              else if(mutableDictionary.objectForKey("\(key)")!.isKindOfClass(NSDictionary))
                              {
                                  mutableDictionary.setValue(mutableDictionary.objectForKey("\(key)")!.RemoveNullValueFromDic(), forKey: key as! String)
                              }
                          }
                          return mutableDictionary
                      }
                  }
              

              【讨论】:

              • NSDictionaryNSMutableDictionary 有本地对应对象时,为什么还要在Swift 中使用它们?函数名也应该以小写字母开头。此外,有很多强制解包可能会导致代码崩溃,并且此答案仅适用于 String 键。
              【解决方案9】:

              使用 reduce 的 Swift 4 示例

              let dictionary = [
                "Value": "Value",
                "Nil": nil
              ]
              
              dictionary.reduce([String: String]()) { (dict, item) in
              
                guard let value = item.value else {
                  return dict
                }
              
                var dict = dict
                dict[item.key] = value
                return dict
              }
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 2016-02-05
                • 2015-01-18
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2022-01-14
                • 2019-09-26
                相关资源
                最近更新 更多