Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to loop through a nested hierarchy of NSDictionaries and NSArrays and convert all to mutable copies?

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?

like image 706
zakdances Avatar asked Mar 23 '13 14:03

zakdances


People also ask

How do I iterate through a nested dictionary?

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.

How do you flatten a dictionary with nested lists and dictionaries in Python?

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.

How do you loop through all nested dictionary values for a for loop in Python?

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.

How do you break nested dictionaries in Python?

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.


1 Answers

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.

like image 109
Martin R Avatar answered Oct 10 '22 22:10

Martin R