Skip to content

Instantly share code, notes, and snippets.

@rbaulin
Created August 8, 2016 19:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rbaulin/f7f658523b4fce73fd3b74112eecc539 to your computer and use it in GitHub Desktop.
Save rbaulin/f7f658523b4fce73fd3b74112eecc539 to your computer and use it in GitHub Desktop.
@implementation NSArray (FDMapping)
// import, array diff
// https://github.com/glebd/google-toolbox-for-mac/blob/master/Foundation/GTMNSArray%2BMerge.m
// https://github.com/Wondermall/Doppelganger
// https://github.com/Basket/BKDeltaCalculator/blob/master/BKDeltaCalculator/BKDeltaCalculator.m
+ (void)ag_mapSourceArray:(NSArray *)source toDestArray:(NSArray *)dest sourceKey:(id (^)(id obj))sourceKeyBlock destKey:(id (^)(id obj))destKeyBlock compare:(NSComparisonResult (^)(id, id))compareBlock match:(void (^)(id, id))matchBlock {
NSArray *sortedSource = [source sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
return compareBlock(sourceKeyBlock(obj1), sourceKeyBlock(obj2));
}];
NSArray *sortedDest = [dest sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
return compareBlock(destKeyBlock(obj1), destKeyBlock(obj2));
}];
// iterators
NSEnumerator *destIterator = [sortedDest objectEnumerator];
NSEnumerator *sourceIterator = [sortedSource objectEnumerator];
id destObject = [destIterator nextObject];
id sourceObject = [sourceIterator nextObject];
while (destObject || sourceObject) {
NSComparisonResult comparison;
if (!destObject) { // if the import list has run out, the import identifier sorts last (i.e. remove remaining objects)
comparison = NSOrderedDescending;
} else if (!sourceObject) { // if managed object list has run out, the import identifier sorts first (i.e. add remaining objects)
comparison = NSOrderedAscending;
} else { // If neither list has run out, compare with the object
comparison = compareBlock(destKeyBlock(destObject), sourceKeyBlock(sourceObject));
}
if (comparison == NSOrderedSame) { // Identifiers match
matchBlock(sourceObject, destObject);
// Move ahead in both lists
destObject = [destIterator nextObject];
sourceObject = [sourceIterator nextObject];
} else if (comparison == NSOrderedAscending) { // Imported item sorts before stored item - add dest object
destObject = [destIterator nextObject];
} else { // The stored item is not among those imported, and should be removed, then move ahead to the next stored item - remove source object
sourceObject = [sourceIterator nextObject];
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment