-4

I have an NSMutableDictionary that contains an array of items (NSDictionary type). I need to remove one particular key (and its associated object) stored in each item. What's the best way to go about this?

Example structure:

   NSDictionary *dict = @{ 
       @"v" : @[ 
          @{ @"key1": @"abc", @"key2" : @"def" },
          @{ @"key1": @"ghi", @"key2" : @"jkl" }, ...
        ]
    };

I want to eliminate all key1 from the nested dictionary element:

@{ 
   @"v" : @[ 
      @{ @"key2" : @"def" },
      @{ @"key2" : @"jkl" }, ...
    ]
}
Sebastian
  • 7,670
  • 5
  • 38
  • 50
Boon
  • 40,656
  • 60
  • 209
  • 315

4 Answers4

2

This should do it:

NSMutableDictionary *dict = [@{
                       @"v" : @[
                               @{ @"key1": @"abc", @"key2" : @"def" },
                               @{ @"key1": @"ghi", @"key2" : @"jkl" }
                               ]
                       } mutableCopy];

NSArray *oldArray = [dict objectForKey:@"v"];
NSMutableArray *newArray = [NSMutableArray array];
[oldArray enumerateObjectsUsingBlock:^(NSDictionary *dictionary, NSUInteger idx, BOOL *stop) {
    NSMutableDictionary *mutableDictionary = [dictionary mutableCopy];
    [mutableDictionary removeObjectForKey:@"key1"];
    [newArray addObject:mutableDictionary];
}];
[dict setObject:newArray forKey:@"v"];
Aaron Brager
  • 65,323
  • 19
  • 161
  • 287
0

For your main dictionary you can enumerate your objects using enumerateKeysAndObjectsUsingBlock: and for the arrays you can use enumerateObjectsUsingBlock

[self.myDictionary enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
    NSArray *array = (NSArray *)obj;
    [arr enumerateObjectsUsingBlock:^(id obj2, NSUInteger idx, BOOL *stop) 
    {
         NSDictionary *dict = (NSDictonary *)obj2;
         // remove item from dict
    }];
}];

I didn't test it but it should give you an idea.

Merlevede
  • 8,140
  • 1
  • 24
  • 39
-1

Enumerate through the NSArray and call [dict removeObjectForKey:@"key1"]for each dictionary.

Edit: If they are NSDictionary instead of NSMutableDictionary, do the following:

NSMutableDictionary *mutableDict = [[NSMutableDictionary alloc] init];
[mutableDict setDictionary:originalDict];
[mutableDict removeObjectForKey:@"key1"];
NSDictionary *newDict = [[NSDictionary alloc] initWithDictionary:mutableDict];

Use newDict however you'd like, probably replace the original one in NSArray

Edit again with entire solution:

NSArray *a = [outerDict objectForKey:@"v"];
NSMutableArray *newArray = [[NSMutableArray alloc] init];
for (NSDictionary d in a) {
    NSMutableDictionary *mutableDict = [[NSMutableDictionary alloc] init];
    [mutableDict setDictionary:d];
    [mutableDict removeObjectForKey:@"key1"];
    NSDictionary *newDict = [[NSDictionary alloc] initWithDictionary:mutableDict];
    [newArray addObject:newDict];
}
[outerDict setObject:newArray ForKey:@"v"];
Simon
  • 1,746
  • 1
  • 13
  • 21
  • How can you call removeObjectForKey when NSArray is storing NSDictionary? – Boon Feb 20 '14 at 03:56
  • If they are `NSDictionary`s then copy them into NSMutableDictionary then call remove. I'm afraid there is no quick and efficient way to do it as NSDictionary is immutable. – Simon Feb 20 '14 at 04:05
  • I don't think your solution will work because key1 is in dictionary inside the array. – Boon Feb 20 '14 at 04:14
  • I just didn't write out the entire solution. My code would fit in the for loop for the array, so you already have each of the inner dictionaries. – Simon Feb 20 '14 at 04:16
  • Your solution won't work. If this question is trivial, I would not ask it here. – Boon Feb 20 '14 at 04:26
  • You keep saying it won't work but don't explain why. If you know what you're talking about, you'd realize most of the proposed answers are effectively equivalent. – Simon Feb 20 '14 at 04:28
  • Because I am not a newbie, I can clearly see your solution won't work before you edited it. And I did explain why it won't but I can't keep explaining you know? – Boon Feb 20 '14 at 04:34
-1

Assuming the inner dictionaries are actually mutable (as your stated) and not inline, you want something like this:

NSString *removeKey = @"key1";
for (NSArray *array in [outerDict allValues])
{
    for (NSMutableDictionary *dict in arrayOfDicts)
    {
        [dict removeObjectForKey:removeKey];
    }
}

... but you still need to have the inner dictionaries mutable. If you want to set it up inline, and have them be mutable, this will work:

NSDictionary *dict = @{
                       @"v" : @[
                               [@{ @"key1": @"abc", @"key2" : @"def" } mutableCopy],
                               [@{ @"key1": @"ghi", @"key2" : @"jkl" } mutableCopy]
                               ]
                       };
greymouser
  • 3,133
  • 19
  • 22