I have an NSDictionary
that contains instances of many different types objects (NSArrays
, NSDictionaries
, NSStrings
, NSNumbers
, etc...). Many of the NSDictionaries
and NSStrings
have their own nested NSDictionaries
and NSArrays
.
How can I loop through the entire hierarchy, from top to bottom, and convert ALL instances of NSDictionaries
and NSArrays
to NSMutableDictionaries
and NSMutableArrays
, respectively?
Is there any easy "recursively make mutable copies" function I'm unaware of? If not, do I just need to loop and type check repeatedly? Can I just replace as I go or do I have rebuild the entire hierarchy?
Nested dictionary means dictionary inside a dictionary and we are going to see every possible way of iterating over such a data structure. For this we will use for loop to iterate through a dictionary to get the all the key , values of nested dictionaries.
Basically the same way you would flatten a nested list, you just have to do the extra work for iterating the dict by key/value, creating new keys for your new dictionary and creating the dictionary at final step. For Python >= 3.3, change the import to from collections.
Iterate over all values of a nested dictionary in python For that we need to again call the items() function on such values and get another iterable sequence of pairs and then look for dict objects in those pairs too. We can achieve all this in a simple manner using recursion.
To delete an item stored in a nested dictionary, we can use the del statement. The del statement lets you delete an object. del is written like a Python break statement , on its own line, followed by the item in the dictionary that you want to delete.
The following method creates a nested (deep) mutable copy of nested arrays, dictionaries and sets. It can also be used to create mutable copies of non-collection objects inside the hierarchy, such as strings.
@interface NSObject (MyDeepCopy)
-(id)deepMutableCopy;
@end
@implementation NSObject (MyDeepCopy)
-(id)deepMutableCopy
{
if ([self isKindOfClass:[NSArray class]]) {
NSArray *oldArray = (NSArray *)self;
NSMutableArray *newArray = [NSMutableArray array];
for (id obj in oldArray) {
[newArray addObject:[obj deepMutableCopy]];
}
return newArray;
} else if ([self isKindOfClass:[NSDictionary class]]) {
NSDictionary *oldDict = (NSDictionary *)self;
NSMutableDictionary *newDict = [NSMutableDictionary dictionary];
for (id obj in oldDict) {
[newDict setObject:[oldDict[obj] deepMutableCopy] forKey:obj];
}
return newDict;
} else if ([self isKindOfClass:[NSSet class]]) {
NSSet *oldSet = (NSSet *)self;
NSMutableSet *newSet = [NSMutableSet set];
for (id obj in oldSet) {
[newSet addObject:[obj deepMutableCopy]];
}
return newSet;
#if MAKE_MUTABLE_COPIES_OF_NONCOLLECTION_OBJECTS
} else if ([self conformsToProtocol:@protocol(NSMutableCopying)]) {
// e.g. NSString
return [self mutableCopy];
} else if ([self conformsToProtocol:@protocol(NSCopying)]) {
// e.g. NSNumber
return [self copy];
#endif
} else {
return self;
}
}
@end
Use it like
NSDictionary *dict = ...;
NSMutableDictionary *mdict = [dict deepMutableCopy];
(Dictionary keys are not copied, only the values).
I am quite sure that I have seen something like this on SO, but cannot find it right now.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With