ios Swift:如何从字典中删除空值?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/27044095/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Swift: How to remove a null value from Dictionary?
提问by Anvar Azizov
I'm new in Swift and I have a problem with filtering NULL values from JSON file and setting it into Dictionary. I getting JSON response from the server with null values and it crashes my app.
我是 Swift 的新手,我在从 JSON 文件中过滤 NULL 值并将其设置到字典中时遇到了问题。我从服务器收到带有空值的 JSON 响应,它使我的应用程序崩溃。
Here is JSON response:
这是 JSON 响应:
"FirstName": "Anvar",
"LastName": "Azizov",
"Website": null,
"About": null,
I will be very appreciated for help to deal with it.
我将非常感谢您的帮助来处理它。
UPD1:At this moment I decided to do it in a next way:
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
}
}
}
采纳答案by Antonio
You can create an array containing the keys whose corresponding values are nil:
您可以创建一个包含对应值为 nil 的键的数组:
let keysToRemove = dict.keys.array.filter { dict[for key in keysToRemove {
dict.removeValueForKey(key)
}
]! == nil }
and next loop through all elements of that array and remove the keys from the dictionary:
然后循环遍历该数组的所有元素并从字典中删除键:
let keysToRemove = dict.keys.filter {
guard let value = dict[dictionary.compactMapValues { let json = [
"FirstName": "Anvar",
"LastName": "Azizov",
"Website": nil,
"About": nil,
]
let result = json.compactMapValues { 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 { dictionary.filter { let result = json.filter { extension Dictionary where Value: AnyObject {
var nullsRemoved: [Key: Value] {
let tup = filter { !(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 { !(jsonResult.filter { !(jsonResult.mapValues { let nullableValueDict: [String : AnyObject?] = [
"first": 1,
"second": "2",
"third": nil
]
// ["first": {Some 1}, "second": {Some "2"}, "third": nil]
is NSNull ? 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"]
}
.1 is NSNull) }
.1 is NSNull) }
return tup.reduce([Key: Value]()) { nullableValueDict.reduce([String : AnyObject]()) { (var dict, e) in
guard let value = e.1 else { return dict }
dict[e.0] = value
return dict
}
.0.updatedValue(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
}
.1.value, forKey: import Foundation
extension Dictionary {
/// Constructs [key:value] from [(key, value)]
init<S: SequenceType
where S.Generator.Element == Element>
(_ seq: S) {
self.init()
self.merge(seq)
}
mutating func merge<S: SequenceType
where S.Generator.Element == Element>
(seq: S) {
var gen = seq.generate()
while let (k, v) = gen.next() {
self[k] = v
}
}
}
let jsonResult:[String: AnyObject] = [
"FirstName": "Anvar",
"LastName" : "Azizov",
"Website" : NSNull(),
"About" : NSNull()]
// using the extension to convert the array returned from flatmap into a dictionary
let clean:[String: AnyObject] = Dictionary(
jsonResult.flatMap(){
// convert NSNull to unset optional
// flatmap filters unset optionals
return (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;
}
.1 is NSNull) ? .None : 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)
}
}
}
})
// clean -> ["LastName": "Azizov", "FirstName": "Anvar"]
.1.key) }
}
}
.1 is NSNull) }
return tup.reduce([Key: Value]()) { (var r, e) in r[e.0] = e.1; return r }
}
}
.value != nil }.mapValues { let testingDict = removeNilValues(dict: ["1":nil, "2":"b", "3":nil, "4":nil, "5":"e"])
print("test result is \(testingDict)")
! }
.value != nil }.mapValues { let people = [
"Paul": 38,
"Sophie": 8,
"Charlotte": 5,
"William": nil
]
let knownAges = people.compactMapValues { 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
}
}
! }
}
print(result) // ["FirstName": "Anvar", "LastName": "Azizov"]
}
}
print(result) // ["FirstName": "Anvar", "LastName": "Azizov"]
}
] else { return false }
return value == nil
}
Update 2017.01.17
更新 2017.01.17
The force unwrapping operator is a bit ugly, although safe, as explained in the comments. There are probably several other ways to achieve the same result, a better-looking way of the same method is:
正如评论中所解释的那样,强制解包运算符虽然安全,但有点难看。可能还有其他几种方法可以实现相同的结果,相同方法的更好看的方法是:
##代码##回答by Marián ?erny
Swift 5
斯威夫特 5
Use compactMapValues
:
使用compactMapValues
:
compactMapValues
has been introduced in Swift 5. For more info see Swift proposal SE-0218.
compactMapValues
已在 Swift 5 中引入。有关更多信息,请参阅 Swift 提案SE-0218。
Example with dictionary
字典示例
##代码##Example including JSON parsing
包含 JSON 解析的示例
##代码##Swift 4
斯威夫特 4
I would do it by combining filter
with mapValues
:
我会通过合并做filter
有mapValues
:
Examples
例子
Use the above examples just replace let result
with
使用上面的例子只是替换let result
为
回答by Daniel T.
I ended up with this in Swift 2:
我在Swift 2 中得到了这个:
##代码##Same answer but for Swift 3:
相同的答案,但对于Swift 3:
##代码##Things get a lot easier in Swift 4. Just use Dictionary's filter
directly.
在Swift 4 中事情变得容易多了。filter
直接使用Dictionary即可。
Or if you don't want to remove the relevant keys, you can do this:
或者,如果您不想删除相关键,您可以这样做:
##代码##Which will replace the NSNull
values with nil
instead of removing the keys.
这将替换NSNull
值nil
而不是删除键。
回答by Eralp Karaduman
Suggesting this approach, flattens optional values and also compatible with Swift 3
建议采用这种方法,将可选值展平并与 Swift 3 兼容
String
key, optional AnyObject?
value dictionary with nil values:
String
键,AnyObject?
具有 nil 值的可选值字典:
nil values removed and transformed into non optional value dictionary
删除 nil 值并转换为非可选值字典
##代码##Redeclaration var dict = dict
is needed due to removal of var parameters in swift 3, so for swift 2,1 it could be;
重声明var dict = dict
需要由于在迅速3去除的变种参数,所以对于迅速2,1它可能是;
Swift 4, would be;
斯威夫特 4,将是;
##代码##回答by Eralp Karaduman
Assuming that you just want to filter out any NSNull
values from a dictionary, this is probably one of the better ways of going about it. It's future-proofed against Swift 3, as far as I know for now:
假设您只想NSNull
从字典中过滤掉任何值,这可能是处理它的更好方法之一。据我目前所知,它是面向未来的 Swift 3:
(With thanks to AirspeedVelocityfor the extension, translated to Swift 2)
(感谢AirspeedVelocity的扩展,翻译成 Swift 2)
##代码##回答by Anita
You can replace the null values to empty string by following function.
您可以通过以下函数将空值替换为空字符串。
##代码##回答by Roman Podymov
Since Swift 4 provides method reduce(into:_:)
for class Dictionary
you can remove nil-values from Dictionary
with the following function:
由于 Swift 4reduce(into:_:)
为类提供了方法,Dictionary
您可以Dictionary
使用以下函数从中删除 nil 值:
You can test it like that:
你可以这样测试:
##代码##回答by Saranjith
Swift 5
斯威夫特 5
compactMapValues(_:)
Returns a new dictionary containing only the key-value pairs that have non-nil values as the result of transformation by the given closure.
##代码##紧凑地图值(_:)
返回一个新字典,该字典仅包含作为给定闭包转换结果的非 nil 值的键值对。
回答by Teja Swaroop
Try to unwrap it with the expected type of values and check for the nill or empty if yes then remove that value from the dictionary.
尝试使用预期类型的值打开它并检查是否为 nill 或为空(如果是),然后从字典中删除该值。
This will work if the values in the dictionary is has empty values
如果字典中的值有空值,这将起作用
回答by Sandeep Kalia
Trim Null form NSDictionary to get ride of crash Pass Dictionary to this function and get result as NSMutableDictionary
修剪 Null 形式 NSDictionary 以摆脱崩溃传递字典到此函数并获得结果作为 NSMutableDictionary
##代码##