Combining NSArrays Through Intersection and Union
Asked Answered
B

5

16

I have two NSArrays A and B that share some common elements, e.g.

A: 1,2,3,4,5 
B: 4,5,6,7

I would like to create a new NSArray consisting of the contents common between the two NSArrays joined with the contents of the second NSArray while maintaining the order of the elements and removing duplicates. That is, I would like (A ∩ B) ∪ B.

The operation on the previous NSArrays would yield:

A ∩ B: 4,5
(A ∩ B) ∪ B: 4,5,6,7

How do I accomplish this in Objective-C?

Barn answered 30/9, 2011 at 21:53 Comment(1)
suppose you wanted something more reasonable than this, but (A ∩ B) ∪ B really doesn't make much sense: it's just B.Lemmons
P
25

Convert the NSArrays to NSSets, the standard set operations are available.

NSArray *a = [NSArray arrayWithObjects:@"1", @"2", @"3", @"4", @"5", nil];
NSArray *b = [NSArray arrayWithObjects:@"4", @"5", @"6", @"7", nil];

NSMutableSet *setA = [NSMutableSet setWithArray:a];
NSSet *setB = [NSSet setWithArray:b];
[setA intersectSet:setB];
NSLog(@"c: %@", [setA allObjects]);

NSLog output: c: (4, 5)

[setA unionSet:setB];
NSLog(@"d: %@", [setA allObjects]);

NSLog output: d: (6, 4, 7, 5)

Prunelle answered 30/9, 2011 at 22:0 Comment(0)
G
15

As others have suggested, you can easily do this with NSSet. However, this will not preserve ordering.

If you want to preserve ordering and you can target OS X 10.7+, then you can use the new NSOrderedSet (and mutable subclass) to do the same thing.

Groce answered 30/9, 2011 at 22:16 Comment(8)
Most seemed to have missed the important aspect of preserving order, which rules out NSSet. My target is iOS 4.3, which does not appear to have the NSOrderedSet library. Any other ideas?Barn
@Mat use the NSSet approach, but then manually extract the elements from B that are in the final set. You'll have to preserve order yourself.Groce
thanks again for the response. I think there is a better way of doing this than resorting to NSSet, which doesn't preserve order. I will probably have to write my own functions/library to do this but wanted to know if the operations were already in-place so I wouldn't be re-inventing the wheel. If so, I will likely post it here in case others run into this sort of issue.Barn
@Mat I'd also like to point out that "(A intersect B) union B" will always result in "B".Groce
Dave, you are correct and I realized this upon implementation. What I would like is that which is unique to B. I believe this can be conveyed with NOT(A union B) intersect NOT(B). Does that represent what I would like correctly? Thanks for the correction!Barn
@Mat that would be just B - A.Groce
Dave, I understand that but what would be the equivalent using intersection and union notation?Barn
@Mat I don't believe that's possible. Why can't you use minus?Groce
D
6

By using NSSet, as others have pointed out. For

NSArray * a = [NSArray arrayWithObjects: ... ];
NSArray * b = [NSArray arratWithObjects: ... ];
NSMutableSet * set = [NSMutableSet setWithArray:a];
[set intersectSet:[NSSet setWithArray:b];
[set unionSet:[NSSet setWithArray:b];

This takes care of dupes but won't preserve order. You'd take the results in "set" and sort them back into an array. There's no native collection functionality that will do it all-- if you prefer to keep the order and worry about dupes separately, use NSMutableArray's -removeObjectsInArray: method, etc.

Domett answered 30/9, 2011 at 22:4 Comment(0)
M
2

(A ∩ B) ∪ B will always give you B, so this is a pretty bizarre thing to want to calculate. It's like saying "Give me the set of all cars that are colored green, combined with the set of all cars". That's going to give you the set of all cars.

Multinuclear answered 14/8, 2015 at 2:1 Comment(0)
S
0

There is an NSSet class you can use to perform these operations.

Suppletory answered 30/9, 2011 at 22:0 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.