Created
August 26, 2016 15:25
-
-
Save rcdilorenzo/8f5591bf98ce37a342236eec9a3b6cc5 to your computer and use it in GitHub Desktop.
A class to diff between two types of arrays (take a look at the test to see how it works)
This file contains hidden or 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
| #import <Foundation/Foundation.h> | |
| typedef BOOL(^NSArrayDiffMatch)(id _Nonnull original, id _Nonnull comparedTo); | |
| @interface NSArrayDiff : NSObject | |
| + (instancetype _Nonnull)newWithOriginal:(NSArray * _Nonnull)original | |
| diffedAgainst:(NSArray * _Nonnull)compareTo | |
| match:(NSArrayDiffMatch _Nonnull)match; | |
| @property (nonatomic, strong, readonly) NSIndexSet * _Nonnull removedIndexes; | |
| @property (nonatomic, strong, readonly) NSArray * _Nonnull removedObjects; | |
| @property (nonatomic, strong, readonly) NSIndexSet * _Nonnull addedIndexes; | |
| @property (nonatomic, strong, readonly) NSArray * _Nonnull addedObjects; | |
| @end |
This file contains hidden or 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
| #import "NSArrayDiff.h" | |
| @interface NSArrayDiff() | |
| @property (nonatomic, strong) NSArrayDiffMatch match; | |
| @property (nonatomic, strong) NSArray *original; | |
| @property (nonatomic, strong) NSArray *comparedTo; | |
| @property (nonatomic, strong) NSMutableIndexSet *removedMutableIndexes; | |
| @property (nonatomic, strong) NSMutableIndexSet *addedMutableIndexes; | |
| @end | |
| @implementation NSArrayDiff | |
| + (instancetype)newWithOriginal:(NSArray *)original diffedAgainst:(NSArray *)compareTo match:(NSArrayDiffMatch)match { | |
| NSArrayDiff *diff = [self new]; | |
| diff.original = original; | |
| diff.comparedTo = compareTo; | |
| diff.match = match; | |
| [diff compare]; | |
| return diff; | |
| } | |
| /** | |
| * Compare is an speed-optimized function to diff | |
| * arrays since it will be often used. Its time | |
| * complexity is O(n^2) and uses the fast enumeration | |
| * for..in loop. | |
| */ | |
| - (void)compare { | |
| NSUInteger index = 0; | |
| for (id original in self.original) { | |
| BOOL found = false; | |
| for (id comparedTo in self.comparedTo) { | |
| if (self.match(original, comparedTo)) { | |
| found = true; | |
| break; | |
| } | |
| } | |
| if (!found) { | |
| [self.removedMutableIndexes addIndex:index]; | |
| } | |
| index++; | |
| } | |
| index = 0; | |
| for (id comparedTo in self.comparedTo) { | |
| BOOL found = false; | |
| for (id original in self.original) { | |
| if (self.match(original, comparedTo)) { | |
| found = true; | |
| break; | |
| } | |
| } | |
| if (!found) { | |
| [self.addedMutableIndexes addIndex:index]; | |
| } | |
| index++; | |
| } | |
| } | |
| - (NSIndexSet *)addedMutableIndexes { | |
| if (!_addedMutableIndexes) { | |
| _addedMutableIndexes = [NSMutableIndexSet new]; | |
| } | |
| return _addedMutableIndexes; | |
| } | |
| - (NSIndexSet *)removedMutableIndexes { | |
| if (!_removedMutableIndexes) { | |
| _removedMutableIndexes = [NSMutableIndexSet new]; | |
| } | |
| return _removedMutableIndexes; | |
| } | |
| - (NSIndexSet *)addedIndexes { | |
| return [self.addedMutableIndexes copy]; | |
| } | |
| - (NSIndexSet *)removedIndexes { | |
| return [self.removedMutableIndexes copy]; | |
| } | |
| - (NSArray *)addedObjects { | |
| return [self.comparedTo objectsAtIndexes:self.addedMutableIndexes]; | |
| } | |
| - (NSArray *)removedObjects { | |
| return [self.original objectsAtIndexes:self.removedMutableIndexes]; | |
| } | |
| @end |
This file contains hidden or 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
| #import <XCTest/XCTest.h> | |
| #define EXP_SHORTHAND | |
| #import "Expecta.h" | |
| #import "NSArrayDiff.h" | |
| @interface NSArrayDiffTests : XCTestCase | |
| @end | |
| @implementation NSArrayDiffTests | |
| - (void)testDiffing { | |
| NSArray *firstNames = @[@"Fred", @"Adam", @"Sam", @"Craig"]; | |
| NSArray *fullNames = @[@"Fred Smith", @"Adam Helbing", @"Nicholas Pizaro", @"Craig Elmot"]; | |
| __block NSArrayDiff *diff; | |
| [self measureBlock:^{ | |
| diff = [NSArrayDiff newWithOriginal:firstNames diffedAgainst:fullNames match:^BOOL(NSString *first, NSString *full) { | |
| return [[[full componentsSeparatedByString:@" "] firstObject] isEqualToString:first]; | |
| }]; | |
| }]; | |
| expect(diff.addedObjects).to.equal(@[@"Nicholas Pizaro"]); | |
| expect(diff.removedObjects).to.equal(@[@"Sam"]); | |
| } | |
| @end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment