2014-02-20 4 views
-4

У меня есть NSMutableDictionary, который содержит массив элементов (тип NSDictionary). Мне нужно удалить один конкретный ключ (и связанный с ним объект), хранящийся в каждом элементе. Каков наилучший способ сделать это?Как удалить элементы из вложенных неизменяемых коллекций

Пример структуры:

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

Я хочу, чтобы устранить все key1 из вложенного словаря элемента:

@{ 
    @"v" : @[ 
     @{ @"key2" : @"def" }, 
     @{ @"key2" : @"jkl" }, ... 
    ] 
} 
+0

Вы имеете в виду, что у вас есть словарь, в котором у вас есть объекты массива, и у каждого массива больше словарей? – Merlevede

+0

Что делает ваш массив словарем? –

+0

@Merlevede да, вы правы. – Boon

ответ

2

Это следует сделать это:

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"]; 
+0

Почему '__block' при объявлении' newArray'? – Sebastian

+0

@Sebastian Обычно блокирует «копировать» переменные внутри них, поэтому изменения переменных не доступны за пределами блока. См. Https://developer.apple.com/library/ios/documentation/cocoa/Conceptual/Blocks/Articles/bxVariables.html#//apple_ref/doc/uid/TP40007502-CH6-SW6 –

+0

(Вам не понадобится ' __block', если вы использовали простой цикл for вместо 'enumerateObjectsUsingBlock:'.) –

-1

Перечислить через NSArray и вызвать [dict removeObjectForKey:@"key1"] для каждого словаря.

Edit: Если они NSDictionary вместо NSMutableDictionary, сделайте следующее:

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

Использование newDict однако вы хотели бы, вероятно, снова заменить оригинальный в NSArray

Редактировать с целым раствором:

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"]; 
+0

Как вы можете вызвать removeObjectForKey, когда NSArray хранит NSDictionary? – Boon

+0

Если они 'NSDictionary', то скопируйте их в NSMutableDictionary, затем вызовите remove. Я боюсь, что нет быстрого и эффективного способа сделать это, поскольку NSDictionary является неизменным. – Simon

+0

Я не думаю, что ваше решение будет работать, потому что key1 находится в словаре внутри массива. – Boon

-1

Предполагая, что внутренние словари фактически изменчивый (как ваш заявленная), а не встроенный, вы хотите что-то вроде этого:

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

... но вы все равно должны иметь внутренние словари изменяемые. Если вы хотите, чтобы настроить его рядный, и у них быть изменяемым, это будет работать:

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

Вам не нужен ключ для внешнего. Это словарный литерал. – Boon

0

Для вашего основного словаря вы можете перечислить свои объекты с помощью enumerateKeysAndObjectsUsingBlock: и для массивов можно использовать 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 
    }]; 
}]; 

Я не проверял, но это должно дать вам идею.

Смежные вопросы