Skip to content

Instantly share code, notes, and snippets.

@RestlessThinker
Last active December 17, 2015 11:59
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 RestlessThinker/5606004 to your computer and use it in GitHub Desktop.
Save RestlessThinker/5606004 to your computer and use it in GitHub Desktop.
#import <Foundation/Foundation.h>
@interface NSDictionary (Flatten)
- (NSMutableArray *)flattenedArray;
@end
#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
#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