How to remove a null value from NSDictionary

2019-02-03 04:46发布

I have a JSON Feed:

{
            "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>" that I cannot figure out how to remove from the NSDictionary before saving it to NSUserDefaults.

Please help me solve this issue. Thankyou!

12条回答
Melony?
2楼-- · 2019-02-03 05:23

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<Key, Value>
    }
 }
查看更多
劫难
3楼-- · 2019-02-03 05:27

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<[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];
}
查看更多
萌系小妹纸
4楼-- · 2019-02-03 05:29

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;
}
查看更多
【Aperson】
5楼-- · 2019-02-03 05:31

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; } )

查看更多
仙女界的扛把子
6楼-- · 2019-02-03 05:35

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 "<null>" 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 ([@"<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. But I'm not sure if this is really the case.

查看更多
乱世女痞
7楼-- · 2019-02-03 05:35

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;
查看更多
登录 后发表回答