Created
March 20, 2012 13:45
Revisions
-
markd2 created this gist
Mar 20, 2012 .There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,13 @@ #import <Foundation/Foundation.h> @interface BNRDiggyDict : NSObject // React to object indexing. Would be nice to have a @protocol for this - (id) objectForKeyedSubscript: (id) key; - (void) setObject: (id) thing forKeyedSubscript: (id<NSCopying>) key; // And for fun, it also can react to scalar indexing. // Returns the N'th key of the top-level collection. - (id) objectAtIndexedSubscript: (NSInteger) index; @end // BWDiggyDict 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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,89 @@ #import "BNRDiggyDict.h" @interface BNRDiggyDict () { NSMutableDictionary *_rootDictionary; } @end // BWDiggyDict @implementation BNRDiggyDict - (id) init { if ((self = [super init])) { _rootDictionary = [NSMutableDictionary dictionary]; } return self; } // init - (NSString *) description { return [_rootDictionary description]; } // description - (NSMutableDictionary *) innerDictionaryForSplitKey: (NSArray *) splitKey { NSMutableDictionary *interim = _rootDictionary; for (int i = 0; i < splitKey.count - 1; i++) { id key = [splitKey objectAtIndex: i]; NSMutableDictionary *next = interim[key]; if (next == nil) { next = [NSMutableDictionary dictionary]; interim[key] = next; } interim = next; } return interim; } // innerDictionaryForSplitKey - (id) objectForKeyedSubscript: (id) key { if (![key respondsToSelector: @selector(componentsSeparatedByString:)]) { return nil; } // Use slashes rather than periods since we're not really doing KVC NSArray *splitKey = [key componentsSeparatedByString: @"/"]; NSMutableDictionary *dict = [self innerDictionaryForSplitKey: splitKey]; id leafKey = [splitKey lastObject]; id result = dict[leafKey]; return result; } // objectForKeyedSubscript - (void) setObject: (id) thing forKeyedSubscript: (id<NSCopying>) key { id idKey = (id) key; // Strip off <NSCopying> so we can send it other messages. if (![idKey respondsToSelector: @selector(componentsSeparatedByString:)]) { return; } // Use slashes rather than periods since we're not really doing KVC NSArray *splitKey = [idKey componentsSeparatedByString: @"/"]; NSMutableDictionary *dict = [self innerDictionaryForSplitKey: splitKey]; id leafKey = [splitKey lastObject]; [dict setObject: thing forKey: leafKey]; } // setObject forKeyedSubscript // And just for fun - (id) objectAtIndexedSubscript: (NSInteger) index { NSArray *keys = [_rootDictionary.allKeys sortedArrayUsingSelector: @selector(compare:)]; return [keys objectAtIndex: index]; } // objectAtIndexedSubscript @end // BWDiggyDict 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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,9 @@ #import <Foundation/Foundation.h> @interface BNRNegativeArray : NSObject // Necessary to declare these. Would be nice to have a protocol to adopt. - (id) objectAtIndexedSubscript: (NSInteger) index; - (void) setObject: (id) thing atIndexedSubscript: (NSInteger) index; @end // BWNegativeArray 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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,55 @@ #import "BNRNegativeArray.h" @interface BNRNegativeArray () { NSMutableArray *_backingstore; } @end // extension @implementation BNRNegativeArray - (id) init { if ((self = [super init])) { _backingstore = [NSMutableArray array]; } return self; } // init - (NSString *) description { return [_backingstore description]; } // descriptioin - (id) objectAtIndexedSubscript: (NSInteger) index { if (index < 0) index = _backingstore.count + index; return [_backingstore objectAtIndex: index]; } // objectAtIndexedSubscript - (void) setObject: (id) thing atIndexedSubscript: (NSInteger) index { if (index < 0) index = _backingstore.count + index; // Mutable array only allows setting the first-empty-index, like // -insertObject:atIndex:. Any past that throws a range exception. // So let's be different and fill in intervening spaces with [NSNull null] // If you want to see @NULL, dupe rdar://10892975 NSInteger toAdd = index - _backingstore.count;; for (int i = 0; i < toAdd; i++) { [_backingstore addObject: [NSNull null]]; } if (index >= _backingstore.count) { [_backingstore addObject: thing]; } else { [_backingstore replaceObjectAtIndex: index withObject: thing]; } } // setObject atIndexedSubscript @end // BWNegativeArray 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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,39 @@ #import <Foundation/Foundation.h> #import "BNRNegativeArray.h" #import "BNRDiggyDict.h" int main (int argc, const char * argv[]) { @autoreleasepool { BNRNegativeArray *negatory = [[BNRNegativeArray alloc] init]; negatory[0] = @"hi"; negatory[1] = @"ohai"; negatory[0] = @"obai"; negatory[10] = @"end!"; NSLog (@"negatory: %@", negatory); NSLog (@"0 - %@", negatory[0]); NSLog (@"5 - %@", negatory[5]); NSLog (@"10 - %@", negatory[10]); NSLog (@"-1 - %@", negatory[-1]); NSLog (@"-10 - %@", negatory[-10]); NSLog (@"-11 - %@", negatory[-11]); BNRDiggyDict *dauchs = [[BNRDiggyDict alloc] init]; dauchs[@"i can has"] = @"cheezburger"; NSLog (@"badger: %@", dauchs); dauchs[@"for/great/justice"] = @"every 'ZIG'"; NSLog (@"badger: %@", dauchs); NSLog (@"TAKE OFF %@", dauchs[@"for/great/justice"]); // Exercise a scalar accessor on the diggydict dauchs[@"Alphabet"] = @"A"; dauchs[@"Badger"] = @"B"; dauchs[@"Carnivorous Tofu"] = @"Nom!"; NSLog (@"second key: %@", dauchs[2]); } return 0; } // main