19

我有一个 JSON 提要:

{
    "count1" = 2;
    "count2" = 2;
    idval = 40;
    level = "<null>";
    "logo_url" = "/assets/logos/default_logo_medium.png";
    name = "Golf Club";
    "role_in_club" = Admin;
}

问题是"<null>". 在将其保存到 NSUserDefaults 之前,我无法弄清楚如何将其从 NSDictionary 中删除。

4

14 回答 14

49

另一种变体,没有(显式)循环:

NSMutableDictionary *dict = [yourDictionary mutableCopy];
NSArray *keysForNullValues = [dict allKeysForObject:[NSNull null]];
[dict removeObjectsForKeys:keysForNullValues];
于 2013-01-03T22:41:13.610 回答
13

遍历字典并查找任何空条目并将其删除。

NSMutableDictionary *prunedDictionary = [NSMutableDictionary dictionary];
for (NSString * key in [yourDictionary allKeys])
{
    if (![[yourDictionary objectForKey:key] isKindOfClass:[NSNull class]])
        [prunedDictionary setObject:[yourDictionary objectForKey:key] forKey:key];
}

之后,prunedDictionary应该在原始字典中有所有非空项。

于 2013-01-03T22:31:29.867 回答
4

这是包含字典和数组的字典的基于类别的递归解决方案,其中值也可以是字典和数组:

文件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

文件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];
}
于 2015-08-31T10:47:14.977 回答
3

使用它从字典中删除 null

- (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;
}
于 2013-01-25T05:13:11.700 回答
0

要删除它,请将其转换为可变字典并删除键“级别”的对象;

NSDictionary* dict = ....;  // this is the dictionary to modify
NSMutableDictionary* mutableDict = [dict mutableCopy];
[mutableDict removeObjectForKey:@"level"];
dict = [mutableDict copy];

如果您不使用 ARC,则需要添加一些对“发布”的调用。

更新:

如果您不知道"<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];

为了找到这些"<null>"值,我使用了字符串比较,因为"<null>"它是您的示例中的一个字符串。但我不确定这是否真的如此。

于 2013-01-03T22:31:53.693 回答
0

我相信这是最节省资源的方式

// 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;
}
于 2015-01-11T20:59:16.793 回答
0

我为 NSJSOn 序列化类创建了一个类别。

创建一个类别并导入类以使用其方法...

// 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;
于 2015-01-19T13:11:38.413 回答
0

Swift -NSNull支持嵌套

首先,我们Dictionary在 Swift 中使用而不是NSDictionary.

要删除任何嵌套级别(包括数组字典)中的任何 外观,请尝试以下操作: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
    }
}

请注意,字典的键应该是String

于 2020-08-21T18:58:38.507 回答
0

我为你的问题尝试了解决方案,我明白了

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

最后答案是

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";
}
于 2015-08-31T11:38:38.010 回答
0

在你的视图控制器中添加这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;
}
于 2018-09-21T09:46:55.087 回答
0

Swift 3.0/4.0解决方案

以下是解决方案,当JSONsub-dictionaries. 这将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>
    }
 }
于 2018-01-03T13:23:16.953 回答
0

修改@sinh99 答案。使用新的 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;
}


于 2019-07-24T04:12:04.400 回答
0

我正在这样做。

NSMutableDictionary *prunedDict = [NSMutableDictionary dictionary];
[self enumerateKeysAndObjectsUsingBlock:^(NSString *key, id obj, BOOL *stop) {
  if (![obj isKindOfClass:[NSNull class]]) {
    prunedDict[key] = obj;
  }
}];
于 2016-08-31T01:41:00.817 回答
0

以下代码在结果在数组或字典中时都可以,您可以通过编辑代码将返回的结果更改为nil或空字符串

该函数是递归的,因此可以解析字典中的数组。

-(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 = "<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;
    }
)
于 2017-04-01T06:51:34.553 回答