Как удалить нулевое значение из 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;
}