NSDictionaryとNSArrayの空要素を再起的に削除する方法

ソースコード

+ (id) removeEmpty:(id)_data
{
	if ( [_data isKindOfClass:[NSDictionary class]] ) {
		return [self removeEmptyForDictionary:(NSDictionary *)_data];
	} else if ( [_data isKindOfClass:[NSArray class]] ) {
		return [self removeEmptyForArray:(NSArray *)_data];
	}
	return _data;
}

+ (NSArray *) removeEmptyForArray:(NSArray *)_data
{
	NSMutableArray* data = [[NSMutableArray alloc] initWithArray:_data];
	for ( int i = 0; i < [_data count]; i++ ) {
		id val = [_data objectAtIndex:i];
		if ( val == nil || [val isKindOfClass:[NSNull class]] ) {
			[data removeObject:val];
			continue;
		}
		if ( [val isKindOfClass:[NSDictionary class]] || [val isKindOfClass:[NSArray class]] ) {
			[data replaceObjectAtIndex:i withObject:[self removeEmpty:data]];
			continue;
		}
	}
	return data;
}

+ (NSDictionary *) removeEmptyForDictionary:(NSDictionary *)_data
{
	NSMutableDictionary* data = [[NSMutableDictionary alloc] initWithDictionary:_data];
	for ( id key in [_data keyEnumerator] ) {
		id val = [_data objectForKey:key];
		if ( val == nil || [val isKindOfClass:[NSNull class]] ) {
			[data removeObjectForKey:key];
			continue;
		}
		if ( [val isKindOfClass:[NSDictionary class]] || [val isKindOfClass:[NSArray class]] ) {
			[data setObject:[self removeEmpty:val] forKey:key];
			continue;
		}
	}
	return data;
}

テストコード

NSMutableDictionary* val1 = [[NSMutableDictionary alloc] init];
[val1 setObject:@"VD1" forKey:@"KK1"];
[val1 setObject:@"VD2" forKey:@"KK2"];
[val1 setObject:[[NSNull alloc] init] forKey:@"KK3"];

NSMutableArray* val2 = [[NSMutableArray alloc] init];
[val2 addObject:@"VA1"];
[val2 addObject:[[NSNull alloc] init]];
[val2 addObject:@"VA3"];
	
NSMutableDictionary* data = [[NSMutableDictionary alloc] init];
[data setObject:@"V1" forKey:@"K1"];
[data setObject:@"V2" forKey:@"K2"];
[data setObject:[[NSNull alloc] init] forKey:@"K3"];
[data setObject:val1 forKey:@"K4"];
[data setObject:val2 forKey:@"K5"];
	
NSLog( @"%@", data );
NSLog( @"%@", [AppDelegate removeEmpty:data] );

検証

元のデータ

{
    K1 = V1;
    K2 = V2;
    K3 = "<null>";
    K4 =     {
        KK1 = VD1;
        KK2 = VD2;
        KK3 = "<null>";
    };
    K5 =     (
        VA1,
        "<null>",
        VA3
    );
}

処理後のデータ

{
    K1 = V1;
    K2 = V2;
    K4 =     {
        KK1 = VD1;
        KK2 = VD2;
    };
    K5 =     (
        VA1,
        VA3
    );
}

nil の要素は消えてますね!