I have a NSMutableArray
oldArray
. Now, at one point, this NSMutableArray
object gets updated with another NSMutableArray
,
addedArray = newArray ∖ (newArray ∩ oldArray)
= newArray ∖ ({@"a",@"c",@"d",@"e",@"f",@"h"} ∩ {@"a",@"b",@"d",@"e",@"g"})
= newArray ∖ {@"a",@"d",@"e"}
= {@"a",@"c",@"d",@"e",@"f",@"h"} ∖ {@"a",@"d",@"e"}
= {@"c",@"f",@"h"}
removedArray = oldArray ∖ (oldArray ∩ newArray)
= oldArray ∖ ({@"a",@"b",@"d",@"e",@"g"} ∩ {@"a",@"c",@"d",@"e",@"f",@"h"})
= oldArray ∖ {@"a",@"d",@"e"}
= {@"a",@"b",@"d",@"e",@"g"} ∖ {@"a",@"d",@"e"}
= {@"b",@"g"}
To find intersections of array, you can view the following SO post: Finding Intersection of NSMutableArrays
I have tried iterating through the old and the new arrays using loops and if conditions, but is it getting really messy and buggy.
This is not a simple problem. First, note that it may have multiple solutions:
a b c d
b c d e
both (a={0, 1, 2, 3}, r={0, 1, 2, 3})
and (a={3}, r={0})
are valid solutions. What you are probably looking for is a minimal solution.
One way to get a minimal solution is by finding the Longest Common Subsequence (LCS) of the two sequences. The algorithm for finding LCS will tell you which elements of the two sequences belong to the LCS, and which do not. Indexes of each element of the original array that is not in LCS go into the removed
array; indexes of elements of the new array that are not in LCS go into the added
array.
Here are a few examples (I parenthesized the elements of LCS):
0 1 2 3 4 5
(a) b (d) (e) g
(a) c (d) (e) f h
The items of old
not in LCS are 1 and 4; the items of new
not in LCS are 1, 4, and 5.
Here is another example:
0 1 2 3
a (b) (c) (d)
(b) (c) (d) e
Now added
is 3
and removed
is 0
.
If both arrays are already sorted in ascending order, you can find the added and removed elements with a single loop over both arrays (using two independent pointers into the array):
NSArray *oldArray = @[@"a",@"b",@"d",@"e",@"g"];
NSArray *newArray = @[@"a",@"c",@"d",@"e",@"f",@"h"];
NSMutableArray *removedArray = [NSMutableArray array];
NSMutableArray *addedArray = [NSMutableArray array];
NSUInteger iold = 0; // index into oldArray
NSUInteger inew = 0; // index into newArray
while (iold < [oldArray count] && inew < [newArray count]) {
// Compare "current" element of old and new array:
NSComparisonResult c = [oldArray[iold] compare:newArray[inew]];
if (c == NSOrderedAscending) {
// oldArray[iold] has been removed
[removedArray addObject:@(iold)];
iold++;
} else if (c == NSOrderedDescending) {
// newArray[inew] has been added
[addedArray addObject:@(inew)];
inew++;
} else {
// oldArray[iold] == newArray[inew]
iold++, inew++;
}
}
// Process remaining elements of old array:
while (iold < [oldArray count]) {
[removedArray addObject:@(iold)];
iold++;
}
// Process remaining elements of new array:
while (inew < [newArray count]) {
[addedArray addObject:@(inew)];
inew++;
}
NSLog(@"removed: %@", removedArray);
NSLog(@"added: %@", addedArray);
Output:
removed: ( 1, 4 ) added: ( 1, 4, 5 )