2013-06-29 2 views
-3
(
    { 
      color = blue; 
    }, 
    { 
      color = blue; 
    }, 
    { 
      color = red; 
    }, 
    { 
      color = white; 
    } 
) 

Это массив словаря, я должен удалить дубликат словаря из массива, соответствующего цвету ключа.Как удалить двуличие из массива словарей в IOS?

+0

Просто для ловли. Эти два блюза - это те же экземпляры одного и того же объекта или те разные экземпляры, которые имеют одинаковое значение? –

+0

Оба являются разными объектами, которые имеют одинаковые значения, на самом деле легко удалить двуличие из простого массива, здесь я столкнулся с проблемой, потому что массив содержал словарь. –

ответ

3

NSSet, чтобы спасти вас в этом случае. Использование:

NSSet *set = [NSSet setWithArray:duplicateArray]; 
NSArray *uniqueArray = [set allObjects]; 

Избегайте использования цикла для этого, потому что если у вас больше циклов объектов, это процесс потребления. Вы можете напрямую использовать NSSet, и он будет работать точно.

+1

Этот подход применим только в том случае, если словари содержат только один ключ (или все словари с одинаковым значением цвета соответствуют друг другу). – Wain

+0

@Wain верен. Взгляните на мой ответ: http://stackoverflow.com/a/17379211/1603072. Он будет работать для любого количества ключей. – Bhavin

+0

Это тоже работает, только если два «синих» объекта относятся к одинаковому экземпляру. NSSEt может очень хорошо хранить несколько экземпляров, которые несут одинаковые значения. –

-1

если обр является массив, из которого вы хотите удалить дубликаты

for(int index = 0;index<arr.count;index++){ 
    NSDictionary *dict = [arr objectAtIndex:index]; 
    for(int i = index-1 ; i>=0 ;i++){ 
     NSDictionary *dictToComp = [arr objectAtIndex:i]; 
     if([[dict objectForKey:@"color"] isEqualToString:[dictToComp objectForKey:@"color"]]){ 
      [arr removeObject:dict]; 
     } 
    } 
} 
+0

То не будет работать для 2 причин. Сначала вам придется изменить это 'i ++' на 'i -', если вы не хотите испортить индексы массива. (если вы не использовали его в качестве индекса, тогда вы даже не получите никого, кроме бесконечного цикла). Во-вторых, удаляя объекты из 'arr', вы испортите свой алгоритм, пропустите итерации и в конечном итоге закончите незаконную отмену idex. –

3

рабочий код:

NSArray *html = @[@{@"color": @("blue")},@{@"color": @("blue")},@{@"color": @("red")},@{@"color": @("yellow")}]; 
NSMutableArray *finalArray = [NSMutableArray array]; 
NSMutableSet *mainSet = [NSMutableSet set]; 
for (NSDictionary *item in html) { 
    //Extract the part of the dictionary that you want to be unique: 
    NSDictionary *dict = [item dictionaryWithValuesForKeys:@[@"color"]]; 
    if ([mainSet containsObject:dict]) { 
     continue; 
    } 
    [mainSet addObject:dict]; 
    [finalArray addObject:item]; 
} 
NSLog(@"%@", finalArray); 
+1

Спасибо, это сработало. –

2

Альтернатива решению Vin, которое, как я считаю, будет работать. Но это не создает результирующий массив. Он управляет существующим. Для этого он создает временные копии для управления итерациями.

NSArray workingCopy = [NSArray arrayWithArray:yourArray]; 

for (int i = 0; i < [workingCopy count] - 1; i++) { // count - 1 just saves time. Works nicely without. 

    for (int j = i+1; j < [workingCopy count]; j++) { 

    if ([[[workingCopy objectAtIndex:i] objectForKey:@"color"] isEqualToString: [[workingCopy objectAtIndex:j] objectForKey:@"color"]] { 

     [yourArray removeOjbect:[[workingCopy objectAtIndex:i] objectForKey:@"color"]] // yourArray must be mutable for this. 
    }  
    } 
} 

Этот алгоритм создает копию исходного массива раньше. Это делается для того, чтобы избежать скрещивания с изменениями в самом массиве, который используется для итераций/перечислений. Затем он выполняет итерацию, хотя копия в двумерном цикле, избегая сравнивать один и тот же объект с самим собой (i никогда не является подходящим для j), и он избегает сопоставления A с B, когда B уже сравнивается с A. Оба достигнуты путем указания j с i + 1. Самая последняя итерация будет i = [workingCopy count]. Тогда j начнется с i+1 и, следовательно, уже будет больше [workingCopy count]. Тело цикла не будет выполняться за один раз. Вот почему петля i уже может закончиться с [workingCopy count] - 1.

То же самое можно сделать без копии исходного массива. Но это требует довольно умных манипуляций с запущенными idices i и j, что не является хорошим стилем программирования, довольно сложным и подверженным ошибкам.

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