web-dev-qa-db-fra.com

Quand est-il préférable d'utiliser un NSSet sur un NSArray?

J'ai utilisé NSSets plusieurs fois dans mes applications, mais je n'en ai jamais créé moi-même.

Quand est-il préférable d'utiliser un NSSet au lieu d'un NSArray et pourquoi?

111
geminiCoder

Lorsque l'ordre des éléments de la collection n'est pas important, les ensembles offrent de meilleures performances pour rechercher des éléments dans la collection.

La raison en est qu'un ensemble utilise des valeurs de hachage pour rechercher des éléments (comme un dictionnaire), tandis qu'un tableau doit parcourir l'ensemble de son contenu pour rechercher un objet particulier.

167
Ole Begemann

L'image de Documentation d'Apple la décrit très bien:

Objective-C Collections

Array est une séquence ordonnée (l'ordre est maintenu lorsque vous ajoutez), une séquence d'éléments

[array addObject:@1];
[array addObject:@2];
[array addObject:@3];
[array addObject:@4];
[array addObject:@6];
[array addObject:@4];
[array addObject:@1];
[array addObject:@2];

[1, 2, 3, 4, 6, 4, 1, 2]

Set est un distinct (pas de doublons), non ordonné liste des éléments

[set addObject:@1];
[set addObject:@2];
[set addObject:@3];
[set addObject:@4];
[set addObject:@6];
[set addObject:@4];
[set addObject:@1];
[set addObject:@2];

[1, 2, 6, 4, 3]
178
James Webster

La meilleure réponse à cette question est propre documentation d’Apple .

enter image description here

La principale différence est que NSArray est destiné à une collection ordonnée et NSSet à une collection non ordonnée.

Plusieurs articles parlent de la différence de vitesse entre les deux, par exemple celui-ci . Si vous parcourez une collection non ordonnée, NSSet est génial. Cependant, dans de nombreux cas, vous devez faire des choses que seul un NSArray peut faire, de sorte que vous sacrifiez la vitesse pour ces capacités.

NSSet

  • Accéder principalement aux articles par comparaison
  • Non ordonné
  • Ne permet pas les doublons

NSArray

  • Peut accéder aux éléments par index
  • Commandé
  • Permet les doublons

C'est tout ce qu'il y a vraiment à faire! Faites-moi savoir si cela vous a été utile.

65
woz

NSOrderedSet est disponible dans iOS 5 et versions ultérieures. Par conséquent, la principale différence est de savoir si vous souhaitez que les objets soient dupliqués dans la structure de données.

12
Jason

NSArray:

  1. Collecte ordonnée de données
  2. Permet les doublons
  3. C'est un objet de type collection

NSSet:

  1. Collecte non ordonnée de données
  2. Ne permet pas les doublons
  3. C'est aussi un objet de type collection
9
iOS Lifee

Un tableau est utilisé pour accéder aux éléments par leur index. Tout élément peut être inséré plusieurs fois dans le tableau. Les tableaux conservent l'ordre de leurs éléments.

Un ensemble est utilisé essentiellement uniquement pour vérifier si l'élément est dans la collection ou non. Les articles n'ont aucun concept d'ordre ou d'indexation. Vous ne pouvez pas avoir un article dans un ensemble deux fois.

Si un tableau veut vérifier s'il contient un élément, il doit vérifier tous ses éléments. Les ensembles sont conçus pour utiliser des algorithmes plus rapides.

Vous pouvez imaginer un ensemble comme un dictionnaire sans valeurs.

Notez que array et set ne sont pas les seules structures de données. Il y en a d'autres, par exemple File d'attente, pile, tas, tas de Fibonacci. Je recommanderais de lire un livre sur les algorithmes et les structures de données.

Voir wikipedia pour plus d'informations.

7
Sulthan
NSArray *Arr;
NSSet *Nset;

Arr=[NSArray arrayWithObjects:@"1",@"2",@"3",@"4",@"2",@"1", nil];
Nset=[NSSet setWithObjects:@"1",@"2",@"3",@"3",@"5",@"5", nil];

NSLog(@"%@",Arr);
NSLog(@"%@",Nset);

le tableau

2015-12-04 11: 05: 40.935 [598: 15730] (1, 2, 3, 4, 2, 1)

l'ensemble

2015-12-04 11: 05: 43.362 [598: 15730] {(3, 1, 2, 5)}

5
abc221

Les principales différences ont déjà été mentionnées dans d'autres réponses.

J'aimerais simplement noter qu'en raison de la manière dont les ensembles et les dictionnaires sont mis en œuvre (c'est-à-dire en utilisant des hachages), il convient de veiller à ne pas utiliser d'objets mutables pour les clés.

Si une clé est mutée, le hachage changera (probablement) aussi, pointant vers un autre index/compartiment dans la table de hachage. La valeur d'origine ne sera pas supprimée et sera réellement prise en compte lors de l'énumération ou de la demande à la structure de sa taille/nombre.

Cela peut rendre très difficile la recherche de bogues.

4
joakim

Ici vous pouvez trouver une comparaison assez détaillée des infrastructures de données NSArray et NSSet.

Brèves conclusions:

Oui, NSArray est plus rapide que NSSet pour simplement tenir et itérer. Aussi peu que 50% plus rapide pour la construction et jusqu'à 500% plus rapide pour les itérations. Leçon: si vous ne devez qu'itérer le contenu, n'utilisez pas de NSSet.

Bien sûr, si vous avez besoin de tester l'inclusion, efforcez-vous d'éviter NSArray. Même si vous avez besoin de tests d'itération et d'inclusion, vous devriez probablement toujours choisir un NSSet. Si vous devez garder votre collection ordonnée et également tester son inclusion, vous devriez envisager de conserver deux collections (un NSArray et un NSSet), chacune contenant les mêmes objets.

NSDictionary est plus lent à construire que NSMapTable - car il doit copier les données de clé. Il compense cela en étant plus rapide à rechercher. Bien sûr, les deux capacités étant différentes, la plupart du temps, cette détermination doit être faite en fonction d'autres facteurs.

3
Che

Vous utiliserez généralement un défini lorsque la vitesse d’accès est essentielle et que l’ordre importe pe, ou déterminé par d’autres moyens (via un prédicat ou un descripteur de tri). Core Data, par exemple, utilise des ensembles lorsque les objets gérés sont accessibles via une relation à plusieurs

2
iDevAmit

Juste pour ajouter un peu, j’utilise parfois parfois juste pour enlever les doublons d’un tableau, comme: -

NSMutableSet *set=[[NSMutableSet alloc]initWithArray:duplicateValueArray]; // will remove all the duplicate values
1
dreamBegin