swift - 从嵌套字典中删除或替换 <null> 值
Posted
技术标签:
【中文标题】swift - 从嵌套字典中删除或替换 <null> 值【英文标题】:swift - delete or replace <null> values from nested dictionary 【发布时间】:2019-09-30 13:29:45 【问题描述】:我有一些来自服务器的数据,我正在使用Alamofire SwiftyJSON
将其转换为[String: Any]
。然后我使用SwiftyPlistManager
将其保存到 plist。重点是SwiftyPlistManager
在保存<null>
的时候崩溃了,所以我需要把<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
,但不知道如何将初始值设置为空字符串或[[]]
,然后检查parced数据是否为<null>
并将初始值保留为默认值。
或者有没有办法列出嵌套字典来替换<null>
to ""
?
【问题讨论】:
var updatedDictionary = Dictionary(uniqueKeysWithValues: yourDictionary.map ($0, $1 != nil ? $1! : "") ) 【参考方案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": <null>,
(所以 <null>
应该被替换与[[]]
。
但是我有大约 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,该值将被替换为空白字符串并返回错误。以上是关于swift - 从嵌套字典中删除或替换 <null> 值的主要内容,如果未能解决你的问题,请参考以下文章