Last active
December 17, 2015 11:59
-
-
Save RestlessThinker/5606004 to your computer and use it in GitHub Desktop.
Flatten NSDictionary using Associated References http://www.restlessthinker.com/blog/programming/flatten-nsdictionary-and-associated-references/
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> | |
@interface NSDictionary (Flatten) | |
- (NSMutableArray *)flattenedArray; | |
@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 "NSDictionary+Flatten.h" | |
#import <objc/runtime.h> | |
static char flattenedArrayKey; | |
@interface NSDictionary (FlattenPrivate) | |
- (void)flattenWithRecursion:(id)object; | |
- (void)enumerate:(id)object depth:(int)depth parent:(id)parent; | |
@end | |
@implementation NSDictionary (Flatten) | |
- (NSMutableArray *)flattenedArray { | |
NSMutableArray *initArray = [[NSMutableArray alloc] init]; | |
objc_setAssociatedObject( self, &flattenedArrayKey, initArray, OBJC_ASSOCIATION_RETAIN ); | |
[self flattenWithRecursion:self]; | |
return (NSMutableArray *)objc_getAssociatedObject( self, &flattenedArrayKey ); | |
} | |
- (void)flattenWithRecursion:(id)object { | |
[self enumerate:object depth:0 parent:nil]; | |
} | |
- (void)enumerate:(id)object depth:(int)depth parent:(id)parent { | |
if( [object isKindOfClass:[NSDictionary class]] ) { | |
for( NSString * key in [object allKeys] ) { | |
id child = [object objectForKey:key]; | |
[self enumerate:child depth:depth+1 parent:object]; | |
} | |
} else if( [object isKindOfClass:[NSArray class]] ) { | |
for( id child in object ) { | |
[self enumerate:child depth:depth+1 parent:object]; | |
} | |
} else if( [object isKindOfClass:[NSSet class]] ) { | |
for( id child in object ) { | |
[self enumerate:child depth:depth+1 parent:object]; | |
} | |
} | |
else{ | |
// not a collection/container it has ended | |
//NSLog(@"Node: %@ depth: %d",[object description],depth); | |
NSMutableArray *assocObject = (NSMutableArray *)objc_getAssociatedObject(self, &flattenedArrayKey); | |
[assocObject addObject:object]; | |
} | |
} | |
@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 <SenTestingKit/SenTestingKit.h> | |
#import "NSDictionary+Flatten.h" | |
@interface NSDictionaryFlattenTests : SenTestCase { | |
} | |
- (void)testFlatten; | |
@end | |
@implementation NSDictionaryFlattenTests | |
- (void)setUp { | |
[super setUp]; | |
} | |
- (void)tearDown { | |
[super tearDown]; | |
} | |
- (void)testFlatten { | |
NSDictionary *collection1 = @{ @"firstName" : @"Foo", @"lastName" : @"Bar", @"middleName" : @"middle" }; | |
NSArray *collection2 = @[@"134234", @"234323"]; | |
NSSet *collection3 = [[NSSet alloc] initWithObjects:@"fooset", @"barset", nil]; | |
NSDictionary *members = [[NSDictionary alloc] initWithObjectsAndKeys:collection1, @"key1", collection2, @"key2", collection3, @"key3", nil]; | |
NSDate *startTime = [NSDate date]; | |
NSMutableArray *testArray = [members flattenedArray]; | |
NSDate *endTime = [NSDate date]; | |
NSTimeInterval executionTime = [endTime timeIntervalSinceDate:startTime]; | |
NSLog(@"execution took approx: %2f seconds", executionTime ); | |
STAssertTrue( [testArray count] == 7, @"should be equal"); | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment