Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Subtract objects in one NSArray from another array

I have two NSArrays:

NSArray *wants = [NSArray arrayWithObjects:
                  @"apples", 
                  @"oranges", 
                  @"pineapple", 
                  @"mango", 
                  @"strawberries", 
                  nil];
NSArray *needs = [NSArray arrayWithObjects:
                  @"apples", 
                  @"pineapple", 
                  @"strawberries", 
                  nil];

And I want to XOR them. Something like wants - needs so that what I have left is

[NSArray arrayWithObjects:
@"oranges", 
@"mango", 
nil];

I would normally go through some heavy looping, but I am sure there is a more practical way. What should I do instead?

like image 988
Jacksonkr Avatar asked May 06 '12 17:05

Jacksonkr


4 Answers

Something like this?

NSMutableArray *array = [NSMutableArray arrayWithArray:wants];
[array removeObjectsInArray:needs];
like image 79
Kirby Todd Avatar answered Oct 17 '22 02:10

Kirby Todd


How about using predicates?

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"NOT (SELF IN %@)", needs];
NSArray *wants_needs = [wants filteredArrayUsingPredicate:predicate];
like image 28
Gyfis Avatar answered Oct 17 '22 02:10

Gyfis


Kirby's answer is fine, but: if you don't care about the order of the elements in the arrays, you should be using sets instead. If the order is important, you might consider NSOrderedSet. You can use the -minusSet: or, for the latter, -minusOrderedSet: methods.

like image 8
Ken Thomases Avatar answered Oct 17 '22 03:10

Ken Thomases


Given two assumptions: that the order is unimportant (or can be restored -- e.g., if the arrays are sorted now)* and that no item appears more than once in either array (although you can use a counted set for this), a set might be a good choice.

The XOR (strictly, the symmetric difference) of two sets is the union minus the intersection:

NSMutableSet * unioned = [NSMutableSet setWithArray:wants];
[unioned unionSet:[NSSet setWithArray:needs]];
NSMutableSet * intersection = [NSMutableSet setWithArray:needs];
[intersection intersectSet:[NSSet setWithArray:wants]];

[unioned minusSet:intersection];

*If order is important, you can use NSOrderedSet.

like image 2
jscs Avatar answered Oct 17 '22 02:10

jscs