[英]Dynamically remove null value from swift dictionary using function
我有以下字典代碼
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
}
請告訴我解決方案
與其使用全局函數(或方法),為什么不使用擴展名使其成為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()
Swift 5 添加了compactMapValues(_:)
,這會讓你做
let filteredDict = dict.compactMapValues { $0 is NSNull ? nil : $0 }
對於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
}
}
Swift 3+:從字典中刪除空值
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"]
斯威夫特 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"]
最干凈的方法,只需 1 行
extension Dictionary {
func filterNil() -> Dictionary {
return self.filter { !($0.value is NSNull) }
}
}
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
}
}
與其使用全局函數(或方法),為什么不使用擴展名使其成為 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
}
}
使用 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
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.