Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Compare NSArray with NSMutableArray adding delta objects to NSMutableArray

I have an NSMutableArray that is populated with objects of strings. For simplicity sake we'll say that the objects are a person and each person object contains information about that person.

Thus I would have an NSMutableArray that is populated with person objects:

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

And so on.

The initial source of data comes from a web server and is populated when my application loads and completes it's initialization with the server. Periodically my application polls the server for the latest list of names.

Currently I am creating an NSArray of the result set, emptying the NSMutableArray and then re-populating the NSMutableArray with NSArray results before destroying the NSArray object.

This seems inefficient to me on a few levels and also presents me with a problem losing table row references which I can work around, but might be creating more work for myself in doing so.

The inefficiency seems to be that I should be able to compare the two arrays and end up with a filtered NSArray. I could then add the filtered set to the NSMutableArray. This would mean that I can simply append new data to the NSMutableArray instead of throwing everything out and re-populating.

Conversely I would need to do the same filter in reverse to see if there are records that need removing from the NSMutableArray.

Is there any method to do this in a more efficient manner? Have I overlooked something in the docs some place that refers to a simpler technique?

I have a problem when I empty the NSMutableArray and re-populate in that any referencing tables lose their selected row state. I can track it and re-select it, but my theory is that using some form of compare and adding objects and removing objects instead of dealing with the whole array in one block might mean I keep my row reference (assuming the item isn't deleted of course).

Any suggestions or help much appreciated.

Update

Would it be just as fast to do a fast enumeration over each comparing each line item as I go? It seems like an expensive operation, but with the last fast enumeration code it might be pretty efficient...

Solution

I ended up going with Abizem's suggestion. Creating the mutable copy of the array and a copy of the object appears to be the slightly faster approach than using sbooth's solution when dealing with large sets of data. Both worked great, I just got more of an edge by using the mutable copy approach. That being said, it did open my eyes up to NSSet where I hadn't looked before.

Thanks for the feedback.

like image 398
Hooligancat Avatar asked Dec 29 '25 19:12

Hooligancat


1 Answers

You can use NSSet to do this type of thing easily (assuming your person objects are unique):

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]];

I'd be surprised if the performance isn't decent, as I'm sure the implementation is optimized.

like image 104
sbooth Avatar answered Jan 01 '26 11:01

sbooth



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!