可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I have a JSON Feed:
{ "count1" = 2; "count2" = 2; idval = 40; level = ""; "logo_url" = "/assets/logos/default_logo_medium.png"; name = "Golf Club"; "role_in_club" = Admin; }
The problem is the "" that I cannot figure out how to remove from the NSDictionary before saving it to NSUserDefaults.
Please help me solve this issue. Thankyou!
回答1:
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.
回答2:
Another variation, without (explicit) loop:
NSMutableDictionary *dict = [yourDictionary mutableCopy]; NSArray *keysForNullValues = [dict allKeysForObject:[NSNull null]]; [dict removeObjectsForKeys:keysForNullValues];
回答3:
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; }
回答4:
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:
#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:
#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
回答5:
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'.
Update:
If you don't know the name of the key(s) with the "" objects, then you have to iterate:
NSDictionary* dict = ....; // this is the dictionary to modify NSMutableDictionary* mutableDict = [dict mutableCopy]; for (id key in dict) { id value = [dict objectForKey: key]; if ([@"" isEqual: value]) { [mutableDict removeObjectForKey:key]; } } dict = [mutableDict copy];
To locate the "" values, I'm using a string comparison since "" is a string in your sample. But I'm not sure if this is really the case.
回答6:
I belive this is the most resource saving way
// category implementation on 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; }
回答7:
I have created a category for NSJSOn serialisation class.
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;
回答8:
I tried the solution for your question and i got it
NSDictionary *dict = [[NSDictionary alloc]initWithObjectsAndKeys:@"2",@"count1",@"2",@"count2",@"40",@"idval",@"",@"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:@""]) { 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"; }
回答9:
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; } }];
回答10:
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
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; }
jsonresult ( { Description = ""; Id = 1; Name = High; }, { Description = ""; Id = 2; Name = Medium; }, { Description = ""; Id = 3; Name = Low; } )
change null ( { Description = ""; Id = 1; Name = High; }, { Description = ""; Id = 2; Name = Medium; }, { Description = ""; Id = 3; Name = Low; } )
回答11:
Swift 3.0/4.0 Solution
Following is the solution, when JSON have sub-dictionaries. This will go-through all the dictionaries, sub-dictionaries of JSON and remove NULL(NSNull) key-value pair from the 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 } }