Best way to compare two NSMutableArray's

Hi! :slight_smile:
I’m a newbie of AppleScriptObjC, so sorry for the simple question, but I cannot find a good answer.
In my application I have a NSMutableArray (dataSource) that I use to populate a tableView. I have also another array (newestDataSource) with the same format but with some new data.
I have to check the second array for missing data from the first array, and add this data to the first array.
How is the best way to achieve this goal but using AppleScriptObjC and not classic Applescript? :confused:
Thank you all.
Renato

Hi,

if the entries in the array are unique and the order doesn’t matter, you could use NSMutableSet,
or “ if the order does matter “ NSMutableOrderedSet. The benefit are methods like minusSet: or intersectSet: to combine or recombine entries and the ability to ignore items to be added multiple times.

set NS.Set classes have also methods to create an NSArray from a set

Thank you very much Stefan for the quick response.
So if I understand correctly that’s the way:

I have my dataSource array with data:

set dataSource to NSMutableArray's alloc()'s init()
set dataForArray to {{title:"Mr",surname:"Doe",phone:"555-555"},{title:"Mr",surname:"Smith",phone:"444-444"}}
dataSource's addObjectsFromArray_(dataForArray)

And I have my other array from a plist file:

set newestDataSource to NSMutableArray's alloc()'s initWithContentsOfFile_(pathToPlist)
-- the data are {{title:"Miss",surname:"Doe",phone:"999-999"},{title:"Mr",surname:"Bishop",phone:"222-222"},}

At the end I need one single array with the union of the two arrays comparing them only by the propriety “surname”. So the result will be an array with three entries: 2 from the first array plus the “Bishop” from the second array (because this surname is not present on the first array).

Now I have to create a NSMutableSet for each array (by the way do I have to use setWithArray_ ?)
After that I use “unionSet_” to combine the entries of the arrays to one new …
and after that again I change the result set to NSMutableArray to populate my table View.

Is that correct?
Do I have to use this approach also if I need only to check arrays only for one propriety?
I never used NSMutableSet I always used just Applescript for this tasks but I think it much slower … can you maybe show one two lines as example on how to implement?

Thank you very very much!

Renato

You can simplify the code a bit:

set dataSource to current application's NSMutableSet's setWithArray_({title:"Mr", surname:"Doe", phone:"555-555"}, {title:"Mr", surname:"Smith", phone:"444-444"})
set newestDataSource to current application's NSArray's arrayWithContentsOfFile_(pathToPlist)
-- add new array, get all objects, then make mutable
set dataSource to dataSource's addObjectsFromArray_(newestDataSource)'s allObjects()'s mutableCopy()

Thank you very much Shane for your suggestion.
I made some test and your line works as expected.
At the end I have an array with all different element from the original array.

The problem is that I need to add an entry to the final array only if the property “surname” is unique, no matter on “title” or “phone”.
Using with my examples this line:

set dataSource to dataSource's addObjectsFromArray_(newestDataSource)'s allObjects()'s mutableCopy()

It will result with a final array with 4 entries because the first one on both arrays, with the same surname (“Doe”) has different “title” and “phone”.
Any way to made an union of the arrays based only on unique “surname” property?

Renato

You might be able to filter one of the arrays using predicates, but this is probably a simpler approach:

set dataSource to current application's NSMutableSet's setWithArray_({title:"Mr", surname:"Doe", phone:"555-555"}, {title:"Mr", surname:"Smith", phone:"444-444"})
set oldSurnames to dataSource's valueForKey_("surname")
set newestDataSource to current application's NSArray's arrayWithContentsOfFile_(pathToPlist)
set newSurnames to newestDataSource's valueForKey_("surname") as list
repeat with i from 1 to count of newSurnames
	if not (oldSurnames's containsObject_(item i of newSurnames)) as boolean then
		dataSource's addObject_(newestDataSource's objectAtIndex_(i - 1))
	end if
end repeat
set dataSource to dataSource's allObjects()'s mutableCopy()

It works like a charm.
Thank you very much.
I still have a question, just to understand, you wrote at the end of your code

set dataSource to dataSource's allObjects()'s mutableCopy()

Is that really necessary? I’m asking that because we already added the missing objects to the array inside the repeat loop isn’t it?
Thanks again
Renato

Before that line, dataSource is a mutable array. Assuming you need a mutable array, allObjects() returns an immutable array, and mutableCopy() gives you a mutable version of it.