2010-03-11 14 views
2

J'ai un NSMutableArray qui est rempli avec des objets de chaînes. Par souci de simplicité, nous dirons que les objets sont une personne et que chaque objet personne contient des informations sur cette personne.Comparer NSArray avec NSMutableArray en ajoutant des objets delta à NSMutableArray

Ainsi j'aurais un NSMutableArray qui est peuplé d'objets personne:

person.firstName 
person.lastName 
person.age 
person.height 

Et ainsi de suite.

La source initiale de données provient d'un serveur Web et est remplie lorsque mon application charge et termine son initialisation avec le serveur. Périodiquement mon application interroge le serveur pour la dernière liste de noms.

Actuellement je crée un NSArray du jeu de résultats, vider le NSMutableArray puis repeupler la NSMutableArray avec NSArray résultats avant de détruire l'objet NSArray.

Cela me semble inefficace sur quelques niveaux et me pose également un problème en perdant des références de lignes de table que je peux contourner, mais je pourrais créer plus de travail pour moi-même. L'inefficacité semble être que je devrais être en mesure de comparer les deux tableaux et se retrouver avec un NSArray filtré. Je pourrais alors ajouter l'ensemble filtré au NSMutableArray. Cela signifierait que je peux simplement ajouter de nouvelles données au NSMutableArray au lieu de tout jeter et de re-peupler. Inversement, j'aurais besoin de faire le même filtre à l'envers pour voir s'il y a des enregistrements qui ont besoin d'être retirés du NSMutableArray.

Existe-t-il une méthode pour le faire de manière plus efficace? Ai-je négligé quelque chose dans les docs quelque part qui se réfère à une technique plus simple?

J'ai un problème lorsque je vide le NSMutableArray et que je répète que toutes les tables de référence perdent leur état de ligne sélectionné. Je peux le suivre et le resélectionner, mais ma théorie est que l'utilisation d'une certaine forme de comparaison et d'ajout d'objets et de suppression d'objets au lieu de traiter tout le tableau dans un bloc peut signifier que je conserve ma référence de ligne (en supposant que supprimé bien sûr).

Toute suggestion ou aide très appréciée.

Mise à jour

Serait-il aussi vite faire une énumération rapide sur chaque comparant chaque élément de ligne que je vais? Il semble comme une opération coûteuse, mais avec le dernier code d'énumération rapide, il peut être assez efficace ...

Solution

J'ai fini par aller avec la suggestion de Abizem. Créer la copie mutable du tableau et une copie de l'objet semble être l'approche légèrement plus rapide que l'utilisation de la solution de booth lorsqu'il s'agit de grands ensembles de données. Les deux ont bien fonctionné, j'ai juste eu plus d'avantage en utilisant l'approche de la copie mutable. Cela étant dit, cela a ouvert mes yeux à NSSet où je n'avais pas regardé auparavant.

Merci pour vos commentaires.

+2

Pourquoi ne pas le tester et voir? Ne pas optimiser prématurément. –

+0

Dans le processus :-) Je vais mettre à jour avec mes conclusions * mais * si quelqu'un a fait cela et sait ... bien ... :-) – Hooligancat

Répondre

2

Deux points.

  1. Le nouveau NSArray contient toutes les données que vous devez afficher. C'est pourquoi vous ajoutez et supprimez du NSMutableArray pour faire correspondre le nouveau.
  2. Vous ne voulez pas perdre l'état sélectionné des lignes dans votre table.

Here're mes suggestions

  1. Plutôt que de vider le NSMutableArray et repeupler avec le nouveau réseau; pourquoi ne pas créer un mutableCopy de NSArray et définir cela comme votre nouveau NSMutableArray? Plutôt que de s'inquiéter de l'ordre des articles (et donc du numéro de ligne sélectionné); que diriez-vous de créer une copie de l'objet sélectionné et après avoir créé votre NSMutableArray comme à l'étape 1, trouvez l'objet correspondant dans le nouveau tableau et définissez-le comme la ligne sélectionnée dans la table en utilisant son nouvel index.
+0

Abizem ... Comme l'approche. Au moins de cette façon, je n'ai pas besoin de comparer chaque élément de chaque tableau les uns avec les autres. Même si j'ai pris la direction 'NSSet', Booth a suggéré qu'il faisait encore une comparaison. Cette approche signifie que j'ai seulement besoin de définir l'index sélectionné une fois et que j'ai terminé. Je vais implémenter chacun et voir si je reçois une différence visuelle/de performance en utilisant l'un sur l'autre. – Hooligancat

+0

Hooligancat ... aussi, si vous faites une sorte de comparaison de l'égalité des objets, assurez-vous d'écrire une méthode 'isEqualTo:' pour votre classe d'objets. Par exemple 'NSString' a la méthode' isEqualToString' qui s'assure que les valeurs des chaînes sont les mêmes plutôt que de voir les pointeurs 'NSString * 'sont les mêmes. – Abizern

+0

Bon point Abizem. Merci – Hooligancat

11

Vous pouvez utiliser NSSet pour faire ce genre de chose facilement (en supposant que vos objets personne sont uniques):

NSSet *existingItems = [NSSet setWithArray:existingItemArray]; 
NSSet *newItems = /* Get the new items from the server */ 

// Determine which items were removed 
NSMutableSet *removedItems = [NSMutableSet setWithSet:existingItems]; 
[removedItems minusSet:newItems]; 

// Determine which items were added 
NSMutableSet *addedItems = [NSMutableSet setWithSet:newItems]; 
[addedItems minusSet:existingItems]; 

// Modify the original array 
[existingItemArray removeObjectsInArray:[removedItems allObjects]]; 
[existingItemArray addObjectsFromArray:[addedItems allObjects]]; 

Je serais surpris si les performances ne sont pas décents, comme je suis sûr de la la mise en œuvre est optimisée.

+0

Merci pour la suggestion de booth. Je n'avais pas envisagé d'utiliser NSSet, mais cette approche est logique à partir d'une approche plus efficace. Je pourrais potentiellement avoir un grand ensemble de données afin que tous les gains d'efficacité que j'obtiens aideront. – Hooligancat

+0

Bien que je n'ai pas posé cette question, c'est exactement ce que j'ai essayé de faire pour le dernier jour et demi, avec absolument aucune chance. C'est un morceau de code élégant et j'ai immédiatement réalisé que c'était ce dont j'avais besoin. Merci beaucoup, ce fut une aubaine à un moment où j'ai juste jeté mon ordinateur portable par la fenêtre! : D –

+0

C'est superbe! Existe-t-il un moyen facile d'obtenir un NSSet avec des éléments qui n'ont pas été ajoutés ou supprimés (c'est-à-dire les mêmes). De cette façon, je pourrais traverser cela et effectuer quelques actions à ce sujet. Je suppose que je suis à la recherche d'un troisième tableau/ensemble qui contient les "doublons" –