2010-09-13 6 views
4

J'ai un tableau qui contient des entrées en double.Restriction Entrée en double dans NSArray

Tout d'abord, est-il possible de limiter les doublons lorsque les données s'insérées? Deuxièmement, si un tableau a déjà des valeurs dupliquées, nous ne pouvons récupérer que des valeurs uniques de ce tableau, j'en ai entendu parler à propos de NSSet, mais je n'ai aucune idée de comment l'utiliser.

Répondre

13

Ne pas utiliser un NSSet.

Vous pouvez uniquement insérer des éléments lors de la création et ne pouvez pas modifier les éléments contenus après l'avoir créé.

Si vous voulez ajouter et supprimer des objets à la volée, vous pouvez utiliser un NSMutableSet.

Voici une démonstration de la façon de l'utiliser à la fois NSSet et NSMutableSet, puis la conversion NSSet retour à un NSArray (Incase vous voulez faire):

- (void) NSMutableSetPrintTest 
{ 
    NSMutableSet *mutableSet = [[NSMutableSet alloc] init]; 

    NSLog(@"Adding 5 objects (3 are duplicates) to NSMutableSet"); 
    NSString *firstString = @"Hello World"; 
    [mutableSet addObject:firstString]; 
    [mutableSet addObject:@"Hello World"]; 
    [mutableSet addObject:@"Goodbye World"]; 
    [mutableSet addObject:@"Goodbye World"]; 
    [mutableSet addObject:@"Goodbye World"]; 

    NSLog(@"NSMutableSet now contains %d objects:", [mutableSet count]); 
    int j = 0; 
    for (NSString *string in mutableSet) { 
     NSLog(@"%d: %@ <%p>", j, string, string); 
     j++; 
    } 

    NSLog(@"Now, if we are done adding and removing things (and only want to check what is in the Set) we should convert to an NSSet for increased performance."); 
    NSSet *immutableSet = [NSSet setWithSet:mutableSet]; 

    NSLog(@"NSSet now contains %d objects:", [immutableSet count]); 
    int i = 0; 
    for (NSString *string in immutableSet) { 
     NSLog(@"%d: %@ <%p>", i, string, string); 
     i++; 
    } 

    [mutableSet release]; mutableSet = nil; 

    NSLog(@"Now, if we are done with the sets, we can convert them back to an NSArray:"); 
    NSArray *array = [immutableSet allObjects]; 

    NSLog(@"NSArray contains %d objects", [array count]); 
    int k = 0; 
    for (NSString *string in array) { 
     NSLog(@"%d: %@ <%p>", k, string, string); 
     k++; 
    } 
} 
+0

ok super, je reçois des valeurs uniques dans mutableSet, que comment copier des éléments de ce mutableSet à un autre tableau, disons tableau b ??? – iscavengers

+0

Mon code vous montre comment faire ceci: 'NSArray * b = [mutableSet copy];' PS: Si ma réponse vous a aidé, vous pouvez le marquer comme correct. À votre santé. –

+0

Come on - "Comment copier des éléments de set à array ??". ** Regardez la documentation de NSSet. ** Il a probablement fallu plus de temps pour écrire ce commentaire que pour double-cliquer sur NSSet et faire défiler jusqu'à la liste des méthodes pour voir 'allObjects'. – bbum

5

Si vous avez entendu parler NSSet, avez-vous lu the documentation? L'API est similaire à NSArray et très simple. Tout comme NSArray vs NSMutableArray, vous utiliseriez NSMutableSet si vous avez besoin de tests d'adhésion à la volée.

+0

si: { \t \t \t [AppDelegate.coffeeArray addObject: coffeeObj] ([AppDelegate.coffeeArray containsObject coffeeObj.message]!); \t // ne contient pas. \t \t} est-ce une meilleure façon de limiter les valeurs en double ???? – iscavengers

+0

Pourquoi cela se traduit-il par tant de rejets? Ma réponse ** montre comment faire cela dans le code ** –

+0

Probablement parce que si quelqu'un sait comment utiliser NSArray, il devrait être capable d'utiliser NSSet. C'est un cas assez clair de l'OP n'utilisant pas les ressources les plus basiques déjà disponibles. (Je vous donnerais un vote si votre code fonctionnait, mais le 'copy' d'un ensemble retourne un ensemble.apprendre à un homme à pêcher). – bbum

9

NSMutableSet est probablement la chose la plus logique à utiliser.

Cependant, soyez averti qu'un ensemble ne maintient pas l'ordre de ses éléments (depuis un ensemble, par définition, est non ordonnée).

Si c'est un problème pour vous, alors vous avez deux options:

  • double fonctionnalité de jeu avec un NSMutableArray en invoquant containsObject: avant chaque appel à addObject: (faisable, mais potentiellement lente, puisque les tableaux ont O (n) temps de recherche)
  • utiliser un autre objet.

Si vous allez avec la deuxième option, je recommande de jeter un oeil à l'excellent cadre CHDataStructures, qui a une sous-classe de NSMutableSet appelé CHOrderedSet, qui est un ensemble qui maintient l'ordre d'insertion. (Et comme il est une sous-classe, il a la même API exactement comme NSMutableSet)

+1

Une réponse très technique (et correcte) comme toujours Dave. +1 –