I need to merge two NSDictionary
s into one provided that if there are dictionaries within the dictionaries, they are also merged.
More or less like jQuery's extend
function.
I need to merge two NSDictionary
s into one provided that if there are dictionaries within the dictionaries, they are also merged.
More or less like jQuery's extend
function.
I think this is what you're looking for:
First, you need to make a deep mutable copy, so you can create a category on NSDictionary
to do this:
@implementation NSDictionary (DeepCopy)
- (id)deepMutableCopy
{
id copy(id obj) {
id temp = [obj mutableCopy];
if ( [temp isKindOfClass:[NSArray class]] ) {
for ( int i = 0 ; i < [temp count] ; i++ )
[temp replaceObjectAtIndex:i withObject:copy([temp objectAtIndex:i])];
} else if ( [temp isKindOfClass:[NSDictionary class]] ) {
NSEnumerator *enumerator = [temp keyEnumerator];
NSString *nextKey;
while (nextKey = [enumerator nextObject])
[temp setObject:copy([temp objectForKey:nextKey]) forKey:nextKey];
}
return temp;
}
return (copy(self));
}
@end
Then, you can call deepMutableCopy
like this:
NSMutableDictionary *someDictionary = [someDict deepMutableCopy];
[someDictionary addEntriesFromDictionary:otherDictionary];
NSDictionary+Merge.h
#import <Foundation/Foundation.h>
@interface NSDictionary (Merge)
+ (NSDictionary *) dictionaryByMerging: (NSDictionary *) dict1 with: (NSDictionary *) dict2;
- (NSDictionary *) dictionaryByMergingWith: (NSDictionary *) dict;
@end
NSDictionary+Merge.m
#import "NSDictionary+Merge.h"
@implementation NSDictionary (Merge)
+ (NSDictionary *) dictionaryByMerging: (NSDictionary *) dict1 with: (NSDictionary *) dict2 {
NSMutableDictionary * result = [NSMutableDictionary dictionary];
[dict2 enumerateKeysAndObjectsUsingBlock: ^(id key, id obj, BOOL *stop) {
if ([obj isKindOfClass: [NSDictionary class]] && [dict1 containsSomethingForKey: key]) {
NSDictionary * newVal = [[dict1 objectForKey: key] dictionaryByMergingWith: (NSDictionary *) obj];
[result setObject: newVal forKey: key];
} else if (![dict1 containsSomethingForKey: key]) {
[result setObject: obj forKey: key];
} else {
[result setObject: [dict1 objectForKey: key] forKey: key];
}
}];
return (NSDictionary *) [[result mutableCopy] autorelease];
}
- (NSDictionary *) dictionaryByMergingWith: (NSDictionary *) dict {
return [[self class] dictionaryByMerging: self with: dict];
}
@end