Как удалить нулевое значение из NSDictionary

У меня есть 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;
}

Проблема заключается в "<null>", что я не могу понять, как удалить из NSDictionary, прежде чем сохранять его в NSUserDefaults.

Пожалуйста, помогите мне решить эту проблему. Thankyou!

Ответы

Ответ 1

Итерации через словарь и поиск нулевых записей и удаление их.

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 должен иметь все ненулевые элементы в оригинальном словаре.

Ответ 2

Другой вариант, без (явного) цикла:

NSMutableDictionary *dict = [yourDictionary mutableCopy];
NSArray *keysForNullValues = [dict allKeysForObject:[NSNull null]];
[dict removeObjectsForKeys:keysForNullValues];

Ответ 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;
}

Ответ 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];
}

Ответ 5

Чтобы удалить его, преобразуйте его в изменяемый словарь и удалите объект для ключевого "уровня";

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

Если вы не используете ARC, вам нужно будет добавить несколько вызовов для "release".

Update:

Если вы не знаете имя ключа (ов) с объектами "<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>" - это строка в вашем примере. Но я не уверен, действительно ли это так.

Ответ 6

Я считаю, что это самый ресурсосберегающий способ

//реализация категории в 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

Я создал категорию для класса сериализации 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;

Ответ 8

Я попробовал решение для вашего вопроса, и я получил его

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

Ответ 9

Я делаю так.

NSMutableDictionary *prunedDict = [NSMutableDictionary dictionary];
[self enumerateKeysAndObjectsUsingBlock:^(NSString *key, id obj, BOOL *stop) {
  if (![obj isKindOfClass:[NSNull class]]) {
    prunedDict[key] = obj;
  }
}];

Ответ 10

следующий код в порядке, когда результат находится в массиве или словаре, вы можете изменить результат, возвращаемый в нуль или пустую строку, отредактировав код

функция рекурсивна, поэтому может анализировать массив в словаре.

-(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 (       {       Описание = ";       Id = 1;       Name = High;   },       {       Описание =" ";       Id = 2;       Name = Medium;   },       {       Описание =" ";       Id = 3;       Name = Low;   } )

изменить null (       {       Описание = ";       Id = 1;       Name = High;   },       {       Описание =" ";       Id = 2;       Name = Medium;   },       {       Описание =" ";       Id = 3;       Name = Low;   } )

Ответ 11

Swift 3.0/4.0 Решение

Ниже приведено решение, когда JSON имеет sub-dictionaries. Это проведет все dictionaries, sub -dictionaries of 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>
    }
 }

Ответ 12

Добавьте эти 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;
}

Ответ 13

В Swift 4.2:

//MARK: - Удалить нулевое значение

func removeNSNull (_ данные: любые) → любые {

if data is NSArray {
    let tempMain = (data as! NSArray).mutableCopy() as! NSMutableArray
    for dict in tempMain {
        if dict is NSNull {
            let Index = tempMain.index(of: dict)
            tempMain.replaceObject(at: Index, with: "")
        }else if dict is NSDictionary {
            let mutableOutDict = removeNSNull(dict)
            let Index = tempMain.index(of: dict)
            tempMain.replaceObject(at: Index, with: mutableOutDict)
        }else if dict is String && (dict as! String == "<null>") {
            let Index = tempMain.index(of: dict)
            tempMain.replaceObject(at: Index, with: "")
        }else if (dict is NSArray) && (dict as! NSArray).count > 0 {
            let tempSub = removeNSNull(dict)
            let Index = tempMain.index(of: dict)
            tempMain.replaceObject(at: Index, with: tempSub)
        }
    }
    return tempMain.mutableCopy() as! NSArray

}else if data is NSDictionary {
    let mutableDict = (data as! NSDictionary).mutableCopy() as! NSMutableDictionary
    for (key, value) in mutableDict {
        if value is NSNull {
            mutableDict.setValue("", forKey: key as! String)
        }else if value is String && (value as! String == "<null>") {
            mutableDict.setValue("", forKey: key as! String)
        }else if (value is NSArray) && (value as! NSArray).count > 0 {
            let array = removeNSNull(value)
            mutableDict.setValue(array, forKey: key as! String)
        }else if (value is NSDictionary){
            let dict = removeNSNull(value)
            mutableDict.setValue(dict, forKey: key as! String)
        }
    }
    return mutableDict.mutableCopy() as! NSDictionary
}else {
    return ""
}

}

Ответ 14

Изменить @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;
}