2014-02-04 3 views
0

У меня есть массив, который содержит несколько словарей, каждый из которых имеет 3 ключа (@"date", @"username", @"text").Несколько словарей в массиве и проверка дубликатов ключей - Objective C

Что я хочу проверить, является ли один и тот же пользователь (@"username") более чем в одном словаре в этом массиве. И если это так, объедините текст для этих «дубликатов» в один словарь.

Я рассмотрел this answer для проверки дубликатов и this one , но я не могу понять, как объединить эти два.

+0

Вам необходимо попробовать их комбинировать, а затем, если у вас есть проблемы, покажите код и обратитесь за помощью. Начните с поиска и регистрации дубликатов. Затем посмотрите на слияние. – Wain

ответ

4

Прыжки здесь, потому что, хотя я думаю, что вы должны работать над кодом самостоятельно первым, я думаю, что Миро ответ более сложный, чем требует проблема, и хотя мне нравится идея использования предикатов в ответе Грега, вот 3-е решение, которое (1) не потребовало бы, чтобы вы изменили структуру данных и (2) ссылались на необходимые циклы ...

Способ Я бы это сделал: создайте NSMutableArray, затем начните добавлять имена пользователей по порядку. Если NSMutableArray уже содержит имя пользователя, не добавляйте еще один экземпляр имени пользователя, а вместо этого объединяйте информацию о словаре.

ex.

// Note: I'm calling your array of user dictionaries userArray. 

// Create a username array to store the usernames and check for duplicates 
NSMutableArray *usernames = [[NSMutableArray alloc] init]; 

// Create a new userArray to store the updated dictionary info, merged 
// entries et. al. 
NSMutableArray *newUserArray = [[NSMutableArray alloc] init]; 

// Go through the array of user dictionaries 
for (NSDictionary *userDict in userArray) { 

    // If the usernames array doesn't already contain the username, 
    // add it to both the usernames array and the newUserArray as is 
    if (![usernames containsObject:[userDict objectForKey:@"username"]]) { 
     [usernames addObject:[userDict objectForKey:@"username"]]; 
     [newUserArray addObject:userDict]; 
    } 

    // Otherwise, merge the userArray entries 
    else { 

     // Get a mutable copy of the dictionary entry at the first instance 
     // with this username 
     int indexOfFirstInstance = [usernames indexOfObject:[userDict objectForKey:@"username"]]; 
     NSMutableDictionary *entry = [[newUserArray objectAtIndex:indexOfFirstInstance] mutableCopy]; 

     // Then combine the "text" or whatever other values you wanted to combine 
     // by replacing the "text" value with the combined text. 
     // (I've done so with a comma, but you could also store the value in an array) 
     [entry setValue:[[entry objectForKey:@"text"] stringByAppendingString:[NSString stringWithFormat:@", %@", [userDict objectForKey:@"text"]]] forKey:@"text"]; 

     // Then replace this newly merged dictionary with the one at the 
     // first instance 
     [newUserArray replaceObjectAtIndex:indexOfFirstInstance withObject:entry]; 
    } 
} 
+0

Работает как шарм, и это на самом деле проще, чем я думал. Спасибо .. – snksnk

+0

Рад слышать! :) –

1

Возможно, что-то вроде этого [непроверенного] примера? Прокручивайте, сохраняйте хэш существующих элементов, и если найден дубликат, то он объединяется с существующим и удаляется.

NSMutableArray main; // this should exist, with content 
NSMutableDictionary *hash = [[NSMutableDictionary alloc] init]; 

// loop through, backwards, as we're attempting to modify array in place (risky) 
for(int i = [main count] - 1; i >= 0; i--){ 
    // check for existing 
    if(hash[main[i][@"username"]] != nil){ 
     int existingIdx = [hash[main[i][@"username"]] integerValue]; // get existing location 
     main[existingIdx][@"text"] = [main[existingIdx][@"text"] stringByAppendingString:main[i][@"text"]]; // "combine text" .. or however you'd like to 
     [main removeObjectAtIndex:i]; // remove duplicate 
    } else { 
     [hash setValue:[[NSNumber alloc] initWithInt:i] forKey:main[i][@"username"]]; // mark existance, with location 
    }  
} 
1

Если вы используете NSMutableDictionary, NSMutableArray и NSMutableString вы можете сделать это с предикатом, как что:

NSMutableDictionary *d1 = [@{@"username": @"Greg", @"text" : [@"text 1" mutableCopy]} mutableCopy]; 
    NSMutableDictionary *d2 = [@{@"username": @"Greg", @"text" : [@"text 2" mutableCopy]} mutableCopy]; 
    NSMutableDictionary *d3 = [@{@"username": @"John", @"text" : [@"text 3" mutableCopy]} mutableCopy]; 
    NSMutableArray *array = [@[d1, d2, d3] mutableCopy]; 

    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"username = %@", @"Greg"]; 
    NSArray *filterArray = [array filteredArrayUsingPredicate:predicate]; 

    NSMutableDictionary * firstDict = filterArray[0]; 
    for (NSDictionary *d in filterArray) 
    { 
     if (firstDict != d) 
     { 
      [firstDict[@"text"] appendString:d[@"text"]]; 
      [array removeObject:d]; 
     } 
    } 
Смежные вопросы