[英]How to remove a null value from NSDictionary
I have a JSON Feed:我有一个 JSON 提要:
{
"count1" = 2;
"count2" = 2;
idval = 40;
level = "<null>";
"logo_url" = "/assets/logos/default_logo_medium.png";
name = "Golf Club";
"role_in_club" = Admin;
}
The problem is the "<null>"
.问题是"<null>"
。 I cannot figure out how to remove it from the NSDictionary before saving it to NSUserDefaults.在将它保存到 NSUserDefaults 之前,我无法弄清楚如何从 NSDictionary 中删除它。
Another variation, without (explicit) loop:另一个变体,没有(显式)循环:
NSMutableDictionary *dict = [yourDictionary mutableCopy];
NSArray *keysForNullValues = [dict allKeysForObject:[NSNull null]];
[dict removeObjectsForKeys:keysForNullValues];
Iterate through the dictionary and look for any null entries and remove them.遍历字典并查找任何空条目并将其删除。
NSMutableDictionary *prunedDictionary = [NSMutableDictionary dictionary];
for (NSString * key in [yourDictionary allKeys])
{
if (![[yourDictionary objectForKey:key] isKindOfClass:[NSNull class]])
[prunedDictionary setObject:[yourDictionary objectForKey:key] forKey:key];
}
After that, prunedDictionary
should have all non-null items in the original dictionary.之后, prunedDictionary
应该包含原始字典中的所有非空项目。
Use this for remove null from dictionary使用它从字典中删除空值
- (NSMutableDictionary *)recursive:(NSMutableDictionary *)dictionary {
for (NSString *key in [dictionary allKeys]) {
id nullString = [dictionary objectForKey:key];
if ([nullString isKindOfClass:[NSDictionary class]]) {
[self recursive:(NSMutableDictionary*)nullString];
} else {
if ((NSString*)nullString == (id)[NSNull null])
[dictionary setValue:@"" forKey:key];
}
}
return dictionary;
}
Here is my category-based recursive solution for dictionaries containing dictionaries and arrays which values can also be dictionaries and arrays:这是我的基于类别的递归解决方案,用于包含字典和数组的字典,其中值也可以是字典和数组:
File NSDictionary+Dario.m :文件NSDictionary+Dario.m :
#import "NSArray+Dario.h"
@implementation NSDictionary (Dario)
- (NSDictionary *) dictionaryByReplacingNullsWithEmptyStrings {
const NSMutableDictionary *replaced = [NSMutableDictionary new];
const id nul = [NSNull null];
const NSString *blank = @"";
for(NSString *key in self) {
const id object = [self objectForKey:key];
if(object == nul) {
[replaced setObject:blank forKey:key];
} else if ([object isKindOfClass:[NSDictionary class]]) {
[replaced setObject:[object dictionaryByReplacingNullsWithEmptyStrings] forKey:key];
} else if ([object isKindOfClass:[NSArray class]]) {
[replaced setObject:[object arrayByReplacingNullsWithEmptyStrings] forKey:key];
} else {
[replaced setObject:object forKey:key];
}
}
return [NSDictionary dictionaryWithDictionary:(NSDictionary*)replaced];
}
@end
File NSArray+Dario.m :文件NSArray+Dario.m :
#import "NSDictionary+Dario.h"
@implementation NSArray (Dario)
- (NSArray *) arrayByReplacingNullsWithEmptyStrings {
const NSMutableArray *replaced = [NSMutableArray new];
const id nul = [NSNull null];
const NSString *blank = @"";
for (int i=0; i<[self count]; i++) {
const id object = [self objectAtIndex:i];
if ([object isKindOfClass:[NSDictionary class]]) {
[replaced setObject:[object dictionaryByReplacingNullsWithEmptyStrings] atIndexedSubscript:i];
} else if ([object isKindOfClass:[NSArray class]]) {
[replaced setObject:[object arrayByReplacingNullsWithEmptyStrings] atIndexedSubscript:i];
} else if (object == nul){
[replaced setObject:blank atIndexedSubscript:i];
} else {
[replaced setObject:object atIndexedSubscript:i];
}
}
return [NSArray arrayWithArray:(NSArray*)replaced];
}
To remove it, convert it into a mutable dictionary and remove the object for key "level";要删除它,请将其转换为可变字典并删除键“级别”的对象;
NSDictionary* dict = ....; // this is the dictionary to modify
NSMutableDictionary* mutableDict = [dict mutableCopy];
[mutableDict removeObjectForKey:@"level"];
dict = [mutableDict copy];
If you don't use ARC, you'll need to add some calls to 'release'.如果您不使用 ARC,则需要添加一些对“release”的调用。
Update:更新:
If you don't know the name of the key(s) with the "<null>"
objects, then you have to iterate:如果您不知道带有"<null>"
对象的键的名称,则必须迭代:
NSDictionary* dict = ....; // this is the dictionary to modify
NSMutableDictionary* mutableDict = [dict mutableCopy];
for (id key in dict) {
id value = [dict objectForKey: key];
if ([@"<null>" isEqual: value]) {
[mutableDict removeObjectForKey:key];
}
}
dict = [mutableDict copy];
To locate the "<null>"
values, I'm using a string comparison since "<null>"
is a string in your sample.为了定位"<null>"
值,我使用了字符串比较,因为"<null>"
是样本中的字符串。 But I'm not sure if this is really the case.但我不确定这是否真的如此。
I belive this is the most resource saving way我相信这是最节省资源的方式
// category implementation on NSDictionary // NSDictionary 上的类别实现
- (NSDictionary *)dictionaryByRemovingNullValues {
NSMutableDictionary * d;
for (NSString * key in self) {
if (self[key] == [NSNull null]) {
if (d == nil) {
d = [NSMutableDictionary dictionaryWithDictionary:self];
}
[d removeObjectForKey:key];
}
}
if (d == nil) {
return self;
}
return d;
}
I have created a category for NSJSOn serialisation class.我为 NSJSOn 序列化类创建了一个类别。
Create a category and import class to use its methods...创建一个类别并导入类以使用其方法...
// Mutable containers are required to remove nulls.
if (replacingNulls)
{
// Force add NSJSONReadingMutableContainers since the null removal depends on it.
opt = opt || NSJSONReadingMutableContainers;
}
id JSONObject = [self JSONObjectWithData:data options:opt error:error];
if ((error && *error) || !replacingNulls)
{
return JSONObject;
}
[JSONObject recursivelyReplaceNullsIgnoringArrays:ignoreArrays withString:replaceString];
return JSONObject;
I tried the solution for your question and i got it我为你的问题尝试了解决方案,我明白了
NSDictionary *dict = [[NSDictionary alloc]initWithObjectsAndKeys:@"2",@"count1",@"2",@"count2",@"40",@"idval",@"<null>",@"level",@"/assets/logos/default_logo_medium.png",@"logo_url",@"Golf Club",@"name",@"role_in_club",@"Admin", nil];
NSMutableDictionary *mutableDict = [dict mutableCopy];
for (NSString *key in [dict allKeys]) {
if ([dict[key] isEqual:[NSNull null]]) {
mutableDict[key] = @"";
}
if([dict[key] isEqualToString:@"<null>"])
{
mutableDict[key] = @"";
}
}
dict = [mutableDict copy];
NSLog(@"The dict is - %@",dict);
Finally the answer is最后答案是
The dict is - {
Admin = "role_in_club";
count1 = 2;
count2 = 2;
idval = 40;
level = "";
"logo_url" = "/assets/logos/default_logo_medium.png";
name = "Golf Club";
}
I am doing in this way.我就是这样做的。
NSMutableDictionary *prunedDict = [NSMutableDictionary dictionary];
[self enumerateKeysAndObjectsUsingBlock:^(NSString *key, id obj, BOOL *stop) {
if (![obj isKindOfClass:[NSNull class]]) {
prunedDict[key] = obj;
}
}];
the following code is ok when the result is in array or dictionary , you can change the result returned to nil or empty string by editing the code当结果在数组或字典中时,以下代码是可以的,您可以通过编辑代码将返回的结果更改为 nil 或空字符串
the function is recursive , so can parse array in dictionary .该函数是递归的,因此可以解析字典中的数组。
-(id)changeNull:(id)sender{
id newObj;
if ([sender isKindOfClass:[NSArray class]]){
NSMutableArray *newArray = [[NSMutableArray alloc] init];
for (id item in sender){
[newArray addObject:[self changeNull:item]];
}
newObj = newArray;
}
else if ([sender isKindOfClass:[NSDictionary class]]){
NSMutableDictionary *newDict = [[NSMutableDictionary alloc] init];
for (NSString *key in sender){
NSDictionary *oldDict = (NSDictionary*)sender;
id item = oldDict[key];
if (![item isKindOfClass:[NSDictionary class]] && ![item isKindOfClass:[NSArray class]]){
if ([item isEqual:[NSNull null]]){
item = @"";
}
[newDict setValue:item forKey:key];
}
else{
[newDict setValue:[self changeNull:item] forKey:key];
}
}
newObj = newDict;
}
return newObj;
}
resulting in:导致:
jsonresult (
{
Description = "<null>";
Id = 1;
Name = High;
},
{
Description = "<null>";
Id = 2;
Name = Medium;
},
{
Description = "<null>";
Id = 3;
Name = Low;
}
)
change null (
{
Description = "";
Id = 1;
Name = High;
},
{
Description = "";
Id = 2;
Name = Medium;
},
{
Description = "";
Id = 3;
Name = Low;
}
)
Swift 3.0/4.0
Solution Swift 3.0/4.0
解决方案
Following is the solution, when JSON
have sub-dictionaries
.以下是解决方案,当JSON
有sub-dictionaries
。 This will go-through all the dictionaries
, sub -dictionaries
of JSON
and remove NULL(NSNull) key-value
pair from the JSON
.这将大大-通过所有的dictionaries
,分-dictionaries
的JSON
和删除NULL(NSNull) key-value
从对JSON
。
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>
}
}
Add this 3 methods in your view controller, and call this method like this way在你的视图控制器中添加这 3 个方法,并像这样调用这个方法
NSDictionary *dictSLoginData = [self removeNull:[result valueForKey:@"data"]];
- (NSDictionary*)removeNull:(NSDictionary *)dict {
NSMutableDictionary *replaced = [NSMutableDictionary dictionaryWithDictionary: dict];
const id nul = [NSNull null];
const NSString *blank = @"";
for (NSString *key in [dict allKeys]) {
const id object = [dict objectForKey: key];
if (object == nul) {
[replaced setObject: blank forKey: key];
} else if([object isKindOfClass: [NSDictionary class]]) {
[replaced setObject: [self replaceNull:object] forKey: key];
} else if([object isKindOfClass: [NSArray class]]) {
[replaced setObject: [self replaceNullArray:object] forKey: key];
}
}
return [NSDictionary dictionaryWithDictionary: replaced];
}
- (NSArray *)replaceNullArray:(NSArray *)array {
const id nul = [NSNull null];
const NSString *blank = @"";
NSMutableArray *replaced = [NSMutableArray arrayWithArray:array];
for (int i=0; i < [array count]; i++) {
const id object = [array objectAtIndex:i];
if (object == nul) {
[replaced replaceObjectAtIndex:i withObject:blank];
} else if([object isKindOfClass: [NSDictionary class]]) {
[replaced replaceObjectAtIndex:i withObject:[self replaceNull:object]];
} else if([object isKindOfClass: [NSArray class]]) {
[replaced replaceObjectAtIndex:i withObject:[self replaceNullArray:object]];
}
}
return replaced;
}
- (NSDictionary *)replaceNull:(NSDictionary *)dict {
const id nul = [NSNull null];
const NSString *blank = @"";
NSMutableDictionary *replaced = [NSMutableDictionary dictionaryWithDictionary: dict];
for (NSString *key in [dict allKeys]) {
const id object = [dict objectForKey: key];
if (object == nul) {
[replaced setObject: blank forKey: key];
} else if ([object isKindOfClass: [NSDictionary class]]) {
[replaced setObject: [self replaceNull:object] forKey: key];
} else if([object isKindOfClass: [NSArray class]]) {
[replaced setObject: [self replaceNullArray:object] forKey: key];
}
}
return replaced;
}
Modify @sinh99 answer.修改@sinh99 答案。 Use a new NSMutableDictionary to collection no-null values and sub-dictionary values.使用新的 NSMutableDictionary 来收集非空值和子字典值。
- (NSMutableDictionary *)recursiveRemoveNullValues:(NSDictionary *)dictionary {
NSMutableDictionary *mDictionary = [NSMutableDictionary new];
for (NSString *key in [dictionary allKeys]) {
id nullString = [dictionary objectForKey:key];
if ([nullString isKindOfClass:[NSDictionary class]]) {
NSMutableDictionary *mDictionary_sub = [self recursiveRemoveNullValues:(NSDictionary*)nullString];
[mDictionary setObject:mDictionary_sub forKey:key];
} else {
if ((NSString*)nullString == (id)[NSNull null]) {
[mDictionary setValue:@"" forKey:key];
} else {
[mDictionary setValue:nullString forKey:key];
}
}
}
return mDictionary;
}
NSNull
supported Swift - 支持嵌套NSNull
First of all, we use Dictionary
in Swift instead of NSDictionary
.首先,我们在 Swift 中使用Dictionary
而不是NSDictionary
。
To remove any NSNull
appearance in any nested level (including arrays and dictionaries ), try this:要删除任何嵌套级别(包括数组和字典)中的任何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
}
}
Note that the key of the dictionary should be String
注意字典的key应该是String
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.