Created
August 8, 2016 19:12
-
-
Save rbaulin/f7f658523b4fce73fd3b74112eecc539 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@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