Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/120.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios Swift:如何从字典中删除空值?_Ios_Json_Swift_Null_Nsdictionary - Fatal编程技术网

Ios Swift:如何从字典中删除空值?

Ios Swift:如何从字典中删除空值?,ios,json,swift,null,nsdictionary,Ios,Json,Swift,Null,Nsdictionary,我是Swift新手,在从JSON文件中过滤空值并将其设置到字典中时遇到问题。 我从服务器获得了带有空值的JSON响应,它使我的应用程序崩溃 以下是JSON响应: "FirstName": "Anvar", "LastName": "Azizov", "Website": null, "About": null, 我将非常感谢您帮助我处理此事 UPD1:此时此刻,我决定用下一种方式: if let jsonResult = responseObject as? [String: AnyObjec

我是Swift新手,在从JSON文件中过滤空值并将其设置到字典中时遇到问题。 我从服务器获得了带有空值的JSON响应,它使我的应用程序崩溃

以下是JSON响应:

"FirstName": "Anvar",
"LastName": "Azizov",
"Website": null,
"About": null,
我将非常感谢您帮助我处理此事

UPD1:此时此刻,我决定用下一种方式:

if let jsonResult = responseObject as? [String: AnyObject] {                    
    var jsonCleanDictionary = [String: AnyObject]()

    for (key, value) in enumerate(jsonResult) {
      if !(value.1 is NSNull) {
         jsonCleanDictionary[value.0] = value.1
      }
    }
}

您可以创建一个数组,其中包含对应值为零的键:

let keysToRemove = dict.keys.array.filter { dict[$0]! == nil }
然后循环该数组的所有元素,并从字典中删除键:

for key in keysToRemove {
    dict.removeValueForKey(key)
}

更新2017.01.17

正如注释中所解释的,强制展开操作符虽然安全,但有点难看。可能还有其他几种方法可以实现相同的结果,相同方法的一种更好的方法是:

let keysToRemove = dict.keys.filter {
  guard let value = dict[$0] else { return false }
  return value == nil
}

假设您只想从字典中过滤掉任何
NSNull
值,这可能是更好的方法之一。就我目前所知,它是针对Swift 3的未来证明:

(感谢扩展,翻译成Swift 2)

<代码>导入基础 扩展字典{ ///从[(键,值)]构造[key:value] 初始化 (续:S){ self.init() 自合并(seq) } 变异函数合并 (续:S){ var gen=序列生成() 而let(k,v)=gen.next(){ 自我[k]=v } } } 让jsonResult:[字符串:AnyObject]=[ “名字”:“Anvar”, “姓氏”:“阿齐佐夫”, “网站”:NSNull(), “关于”:NSNull()] //使用扩展将flatmap返回的数组转换为字典 let clean:[字符串:AnyObject]=字典( jsonResult.flatMap(){ //将NSNull转换为unset可选 //flatmap过滤器取消设置选项 返回($0.1为空)?。无:$0 }) //clean->[“LastName”:“Azizov”,“FirstName”:“Anvar”]
我在《Swift 2》中以这个结尾:

extension Dictionary where Value: AnyObject {

    var nullsRemoved: [Key: Value] {
        let tup = filter { !($0.1 is NSNull) }
        return tup.reduce([Key: Value]()) { (var r, e) in r[e.0] = e.1; return r }
    }
}
extension Dictionary {

    /// An immutable version of update. Returns a new dictionary containing self's values and the key/value passed in.
    func updatedValue(_ value: Value, forKey key: Key) -> Dictionary<Key, Value> {
        var result = self
        result[key] = value
        return result
    }

    var nullsRemoved: [Key: Value] {
        let tup = filter { !($0.1 is NSNull) }
        return tup.reduce([Key: Value]()) { $0.0.updatedValue($0.1.value, forKey: $0.1.key) }
    }
}
相同的答案,但对于Swift 3

extension Dictionary where Value: AnyObject {

    var nullsRemoved: [Key: Value] {
        let tup = filter { !($0.1 is NSNull) }
        return tup.reduce([Key: Value]()) { (var r, e) in r[e.0] = e.1; return r }
    }
}
extension Dictionary {

    /// An immutable version of update. Returns a new dictionary containing self's values and the key/value passed in.
    func updatedValue(_ value: Value, forKey key: Key) -> Dictionary<Key, Value> {
        var result = self
        result[key] = value
        return result
    }

    var nullsRemoved: [Key: Value] {
        let tup = filter { !($0.1 is NSNull) }
        return tup.reduce([Key: Value]()) { $0.0.updatedValue($0.1.value, forKey: $0.1.key) }
    }
}
或者,如果不想删除相关密钥,可以执行以下操作:

jsonResult.mapValues { $0 is NSNull ? nil : $0 }

这将用
nil
替换
NSNull
值,而不是删除键。

建议使用此方法,使可选值变平,并且与Swift 3兼容

String
key,可选
AnyObject?
value字典,值为零:

let nullableValueDict: [String : AnyObject?] = [
    "first": 1,
    "second": "2",
    "third": nil
]

// ["first": {Some 1}, "second": {Some "2"}, "third": nil]
删除零值并转换为非可选值字典

nullableValueDict.reduce([String : AnyObject]()) { (dict, e) in
    guard let value = e.1 else { return dict }
    var dict = dict
    dict[e.0] = value
    return dict
}

// ["first": 1, "second": "2"]
由于删除了swift 3中的var参数,因此需要重新声明
var dict=dict
,因此对于swift 2,1,可能需要重新声明

nullableValueDict.reduce([String : AnyObject]()) { (var dict, e) in
    guard let value = e.1 else { return dict }
    dict[e.0] = value
    return dict
}
斯威夫特4号,将是

let nullableValueDict: [String : Any?] = [
    "first": 1,
    "second": "2",
    "third": nil
]

let dictWithoutNilValues = nullableValueDict.reduce([String : Any]()) { (dict, e) in
    guard let value = e.1 else { return dict }
    var dict = dict
    dict[e.0] = value
    return dict
}

我只需要解决一个一般情况,其中NSNull可以嵌套在字典中的任何级别,甚至是数组的一部分:

extension Dictionary where Key == String, Value == Any {

func strippingNulls() -> Dictionary<String, Any> {

    var temp = self
    temp.stripNulls()
    return temp
}

mutating func stripNulls() {

    for (key, value) in self {
        if value is NSNull {
            removeValue(forKey: key)
        }
        if let values = value as? [Any] {
            var filtered = values.filter {!($0 is NSNull) }

            for (index, element) in filtered.enumerated() {
                if var nestedDict = element as? [String: Any] {
                    nestedDict.stripNulls()

                    if nestedDict.values.count > 0 {
                        filtered[index] = nestedDict as Any
                    } else {
                        filtered.remove(at: index)
                    }
                }
            }

            if filtered.count > 0 {
                self[key] = filtered
            } else {
                removeValue(forKey: key)
            }
        }

        if var nestedDict = value as? [String: Any] {

            nestedDict.stripNulls()

            if nestedDict.values.count > 0 {
                self[key] = nestedDict as Any
            } else {
                self.removeValue(forKey: key)
            }
        }
    }
}
扩展字典,其中Key==String,Value==Any{
func strippingNulls()->字典{
var temp=自
临时stripNulls()
返回温度
}
变异func stripNulls(){
对于自我中的(关键、价值){
如果值为空{
移除值(forKey:key)
}
如果let values=值为?[任何]{
var filtered=values.filter{!($0为NSNull)}
对于filtered.enumerated()中的(索引,元素){
如果var nestedDict=元素为?[字符串:任意]{
nestedDict.stripNulls()
如果nestedDict.values.count>0{
过滤[索引]=嵌套的信息,如有
}否则{
已筛选。删除(位于:索引)
}
}
}
如果已筛选。计数>0{
自[键]=已过滤
}否则{
移除值(forKey:key)
}
}
如果var nestedDict=值为?[字符串:任意]{
nestedDict.stripNulls()
如果nestedDict.values.count>0{
self[键]=嵌套的ICT(如有)
}否则{
self.removeValue(forKey:key)
}
}
}
}
}

我希望这对其他人有帮助,我欢迎改进


(注意:这是Swift 4)

JSON
子字典时,以下是解决方案。
这将遍历
JSON
的所有
字典、子字典,并从
JSON
中删除NULL
(NSNull)
键值对

extension Dictionary {

    func removeNull() -> Dictionary {
        let mainDict = NSMutableDictionary.init(dictionary: self)
        for _dict in mainDict {
            if _dict.value is NSNull {
                mainDict.removeObject(forKey: _dict.key)
            }
            if _dict.value is NSDictionary {
                let test1 = (_dict.value as! NSDictionary).filter({ $0.value is NSNull }).map({ $0 })
                let mutableDict = NSMutableDictionary.init(dictionary: _dict.value as! NSDictionary)
                for test in test1 {
                    mutableDict.removeObject(forKey: test.key)
                }
                mainDict.removeObject(forKey: _dict.key)
                mainDict.setValue(mutableDict, forKey: _dict.key as? String ?? "")
            }
            if _dict.value is NSArray {
                let mutableArray = NSMutableArray.init(object: _dict.value)
                for (index,element) in mutableArray.enumerated() where element is NSDictionary {
                    let test1 = (element as! NSDictionary).filter({ $0.value is NSNull }).map({ $0 })
                    let mutableDict = NSMutableDictionary.init(dictionary: element as! NSDictionary)
                    for test in test1 {
                        mutableDict.removeObject(forKey: test.key)
                    }
                    mutableArray.replaceObject(at: index, with: mutableDict)
                }
                mainDict.removeObject(forKey: _dict.key)
                mainDict.setValue(mutableArray, forKey: _dict.key as? String ?? "")
            }
        }
        return mainDict as! Dictionary<Key, Value>
    }
 }
扩展字典{
func removeNull()->字典{
让mainDict=NSMutableDictionary.init(dictionary:self)
主语中的主语{
如果_dict.value为NSNull{
mainDict.removeObject(forKey:_dict.key)
}
如果_dict.value为NSDictionary{
设test1=(_dict.value as!NSDictionary).filter({$0.value为NSNull}).map({$0})
让mutableDict=NSMutableDictionary.init(dictionary:_dict.value as!NSDictionary)
用于test1中的测试{
mutableDict.removeObject(forKey:test.key)
}
mainDict.removeObject(forKey:_dict.key)
mainDict.setValue(可变dict,forKey:_dict.key作为?字符串??)
}
如果_dict.value是NSArray{
让mutableArray=NSMutableArray.init(对象:_dict.value)
对于mutableArray.enumerated()中的(索引,元素),其中元素为NSDictionary{
设test1=(元素为!NSDictionary).filter({$0.value为NSNull}).map({$0})
让mutableDict=NSMutableDictionary.init(dictionary:element as!NSDictionary)
用于test1中的测试{
mutableDict.removeObject(forKey:test.key)
}
replaceObject(位于:index,带:mutableDict)
}
mainDict.removeObject(forKey:_dict.key)
mainDict.setValue(可变数组,forKey:_
func removeNilValues<K,V>(dict:Dictionary<K,V?>) -> Dictionary<K,V> {

    return dict.reduce(into: Dictionary<K,V>()) { (currentResult, currentKV) in

        if let val = currentKV.value {

            currentResult.updateValue(val, forKey: currentKV.key)
        }
    }
}
let testingDict = removeNilValues(dict: ["1":nil, "2":"b", "3":nil, "4":nil, "5":"e"])
print("test result is \(testingDict)")
func removeNullFromDict (dict : NSMutableDictionary) -> NSMutableDictionary
{
    let dic = dict;

    for (key, value) in dict {

        let val : NSObject = value as! NSObject;
        if(val.isEqual(NSNull()))
        {
            dic.setValue("", forKey: (key as? String)!)
        }
        else
        {
            dic.setValue(value, forKey: key as! String)
        }

    }

    return dic;
}
dictionary.compactMapValues { $0 }
let json = [
    "FirstName": "Anvar",
    "LastName": "Azizov",
    "Website": nil,
    "About": nil,
]

let result = json.compactMapValues { $0 }
print(result) // ["FirstName": "Anvar", "LastName": "Azizov"]
let jsonText = """
  {
    "FirstName": "Anvar",
    "LastName": "Azizov",
    "Website": null,
    "About": null
  }
  """

let data = jsonText.data(using: .utf8)!
let json = try? JSONSerialization.jsonObject(with: data, options: [])
if let json = json as? [String: Any?] {
    let result = json.compactMapValues { $0 }
    print(result) // ["FirstName": "Anvar", "LastName": "Azizov"]
}
dictionary.filter { $0.value != nil }.mapValues { $0! }
let result = json.filter { $0.value != nil }.mapValues { $0! }
func trimNullFromDictionaryResponse(dic:NSDictionary) -> NSMutableDictionary {
    let allKeys = dic.allKeys
    let dicTrimNull = NSMutableDictionary()
    for i in 0...allKeys.count - 1 {
        let keyValue = dic[allKeys[i]]
        if keyValue is NSNull {
            dicTrimNull.setValue("", forKey: allKeys[i] as! String)
        }
        else {
            dicTrimNull.setValue(keyValue, forKey: allKeys[i] as! String)
        }
    }
    return dicTrimNull
}
let people = [
    "Paul": 38,
    "Sophie": 8,
    "Charlotte": 5,
    "William": nil
]

let knownAges = people.compactMapValues { $0 }
extension Dictionary where Key == String, Value == Optional<Any> {
    func discardNil() -> [Key: Any] {
        return self.compactMapValues({ $0 })
    }
}
public func toDictionary() -> [String: Any] {
    let emailAddress: String? = "test@mail.com"
    let phoneNumber: String? = "xxx-xxx-xxxxx"
    let newPassword: String = "**********"

    return [
        "emailAddress": emailAddress,
        "phoneNumber": phoneNumber,
        "passwordNew": newPassword
    ].discardNil()
}
//
//  Collection+SF.swift
//  PanoAI
//
//  Created by Forever Positive on 2021/1/30.
//

import Foundation

extension Array where Element == Optional<Any>{
    var trimed:[Any] {
       var newArray = [Any]()
        for item in self{
            if let item = item as? [Any?] {
                newArray.append(contentsOf: item.trimed)
            }else if item is NSNull || item == nil {
                //skip
            }else if let item = item{
                newArray.append(item)
            }
        }
        return newArray
    }
}

extension Dictionary where Key == String, Value == Optional<Any> {
    var trimed:[Key: Any] {
        return self.compactMapValues({ v in
            if let dic = v as? [String:Any?] {
                return dic.trimed
            }else if let _ = v as? NSNull {
                return nil;
            }else if let array = v as? [Any?] {
                return array.trimed;
            }else{
                return v;
            }
        })
    }
}

// MARK: - Usage
//let dic:[String:Any?] = ["a":"a","b":nil,"c":NSNull(),"d":["1":"1","2":nil,"3":NSNull(),"4":["a","b",nil,NSNull()]],"e":["a","b",nil,NSNull()]]
//print(dic.trimed)
let cleanDictionary = originalDictionary.reduce(into: [String: Any]()) { $0[$1.key] = $1.value }
let originalDictionary = [
    "one": 1,
    "two": nil,
    "three": 3]

let cleanDictionary = originalDictionary.reduce(into: [String: Any]()) { $0[$1.key] = $1.value }    
for element in cleanDictionary {
    print(element)
}