2011-08-17 6 views
2

Je le code suivant:combinant NSMutableSets

NSMutableSet* localSet = [[NSMutableSet alloc] initWithArray:symbols]; 
NSMutableArray* fetchedSymbolsArray = [NSMutableArray array]; 

for (NSDictionary* symbol in fetchedSymbols) { 
    [fetchedSymbolsArray addObject:[NSDictionary dictionaryWithObject:[symbol valueForKey:@"symbol"] forKey:@"symbol"]]; 
} 

NSMutableSet* serverSet = [[NSMutableSet alloc] initWithArray:fetchedSymbolsArray]; 

[localSet unionSet:serverSet]; 

for (NSDictionary* symbol in localSet) { 
    NSLog(@"%@",[symbol valueForKey:@"symbol"]); 
} 

Je veux tout ServerSet pour être en localSet. Ce code ne reflète pas cela.

Il serait également préférable si aucun doublon n'a été ajouté à localSet.

EDIT: Voici mon journal:

2011-08-16 17:46:28.887 Stream[94612:207] YHOO 
2011-08-16 17:46:28.887 Stream[94612:207] GOOG 
2011-08-16 17:46:28.887 Stream[94612:207] INTC 
2011-08-16 17:46:28.888 Stream[94612:207] BIDU 
2011-08-16 17:46:28.888 Stream[94612:207] INTC 
2011-08-16 17:46:28.888 Stream[94612:207] BIDU 
2011-08-16 17:46:28.888 Stream[94612:207] AAPL 
2011-08-16 17:46:28.888 Stream[94612:207] AAPL 
2011-08-16 17:46:28.889 Stream[94612:207] AMD 
2011-08-16 17:46:28.889 Stream[94612:207] GMCR 
+0

vous fournirions la sortie de 'NSLog (@ "% @", localSet)' (à la fin de votre code)? – paulmelnikow

Répondre

6

essayer [localSet unionSet:serverSet]

EDIT

le code est ici qui utilise simplement des symboles au lieu de NSDictionary s:

NSArray *symbols = [NSArray arrayWithObjects:@"AAPL",@"GOOG",@"INTC",@"YHOO",nil]; 

NSArray *fetchedSymbols = [NSArray arrayWithObjects:@"AMD",@"BIDU",@"GOOG",@"GMCR",@"INTC",@"YHOO",nil]; 


NSMutableSet* localSet = [[NSMutableSet alloc] initWithArray:symbols]; 
NSMutableSet* serverSet = [[NSMutableSet alloc] initWithArray:fetchedSymbols]; 

[localSet unionSet:serverSet]; 

for (id symbol in localSet) { 
    NSLog(@"%@",symbol); 
} 

2011-08-16 18:25:22.107 so7086790[39810:a0f] YHOO 
2011-08-16 18:25:22.116 so7086790[39810:a0f] AMD 
2011-08-16 18:25:22.116 so7086790[39810:a0f] AAPL 
2011-08-16 18:25:22.116 so7086790[39810:a0f] INTC 
2011-08-16 18:25:22.117 so7086790[39810:a0f] GMCR 
2011-08-16 18:25:22.117 so7086790[39810:a0f] GOOG 
2011-08-16 18:25:22.118 so7086790[39810:a0f] BIDU 
+0

Cool maintenant ils sont tous ajoutés. Le problème est qu'il y a des doublons. Comment puis-je supprimer des dupes de l'ensemble? –

+0

C'est probablement parce que les membres de l'ensemble que vous considérez égaux ne sont pas vraiment égaux dans la façon dont ils sont testés par 'NSSet' (c'est-à-dire qu'ils retournent' false' quand ils sont envoyés 'isEqual:'). Après avoir regardé votre journal, je suis à peu près sûr que c'est le cas. Le résultat 'valueForKey: @" symbol "' est le même pour les dictionnaires, mais les dictionnaires eux-mêmes ne sont pas identiques. – SSteve

+0

Je vois. Dans cet esprit, comment puis-je vérifier la valeur de chaîne dans le dictionnaire, ou supprimer des dupes? –

0

Vous avez votre serverSet et localSet dans le mauvais sens dans l'union - l'ensemble en cours de modification est le récepteur de la méthode "unionSet:", pas l'argument.

NSMutableSet* localSet = [[NSMutableSet alloc] initWithArray:symbols]; 
NSMutableArray* fetchedSymbolsArray = [NSMutableArray array]; 

for (NSDictionary* symbol in fetchedSymbols) { 
    [fetchedSymbolsArray addObject:[NSDictionary dictionaryWithObject:[symbol valueForKey:@"symbol"] forKey:@"symbol"]]; 
} 

NSMutableSet* serverSet = [[NSMutableSet alloc] initWithArray:fetchedSymbolsArray]; 

[localSet unionSet:serverSet]; 

for (NSDictionary* symbol in localSet) { 
    NSLog(@"%@",[symbol valueForKey:@"symbol"]); 
} 

Remarquer que ce, par définition, ne permettra pas à des entrées en double. Mais cela ne signifie pas que vous n'aurez pas de doublons de valeurs dans le dictionnaire, cela signifie que vous n'aurez pas deux fois le même dictionnaire "égal" (deux dictionnaires sont égaux s'ils ont chacun le même nombre d'entrées et, pour une clé donnée, les objets de valeur correspondants dans chaque dictionnaire satisfont le test isEqual:).

Pour éviter les doublons d'une valeur de dictionnaire particulière, vous devez les ajouter vous-même. Je vous recommande de créer un ensemble temporaire contenant les valeurs réelles de la clé "symbol" et d'utiliser cet ensemble pour tester s'il a déjà été ajouté.

NSMutableSet *localSetValues = [[NSMutableSet alloc] init]; 

// Add local set values 
for (NSDictionary *symbol in localSet) { 
    [localSetValues addObject:[symbol valueForKey:@"symbol"]]; 
} 
// Add server set, conditionally 
for (NSDictionary *symbol in serverSet) { 
    if (![localSetValues containsObject:[symbol valueForKey:@"symbol"]]) { 
     [localSet addObject:symbol]; 
    } 
} 

// Cleanup 
[localSetValues release]; 

Au lieu de

[localSet unionSet:serverSet]; 
+0

Merci, mis à jour, mais voir mon journal, les dupes apparaissent. –

+0

Je ne pense pas que ce que vous dites sur les entrées en double est correct. Il semble que NSSet va dédoubler les dictionnaires qui sont vraiment identiques.Par exemple, ceci imprime un ensemble contenant un seul dictionnaire, malgré deux instances distinctes: NSDictionary * dict1 = [NSDictionary dictionaryWithObject: @ "AAPL" forKey: @ "symbole"]; NSDictionary * dict2 = [NSDictionary dictionaryWithObject: @ "AAPL" forKey: @ "symbole"]; NSMutableSet * set = [NSMutableSet setWithObject: dict1]; [set addObject: dict2]; NSLog (@ "% @", ensemble); – paulmelnikow

+0

Oui vous avez raison, je n'ai pas fait la distinction entre les dictionnaires égaux et inégaux très clair. Actualisé. – Johnus