Created
July 31, 2013 13:49
-
-
Save aspitz/6122137 to your computer and use it in GitHub Desktop.
A dictionary that keeps track of the order that elements were added to it
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
@interface OrderedDictionary : NSObject <NSCopying, NSCoding>{ | |
NSMutableDictionary *_dictionary; | |
NSMutableArray *_array; | |
} | |
@property (readonly) NSUInteger count; | |
- (id)init; | |
- (id)initWithCapacity:(NSUInteger)capacity; | |
+ (id)dictionary; | |
+ (id)dictionaryWithCapacity:(NSUInteger)capacity; | |
- (void)setObject:(id)object forKeyedSubscript:(id<NSCopying>)aKey; | |
- (id)objectForKeyedSubscript:(id)key; | |
- (id)objectAtIndexedSubscript:(NSUInteger)idx; | |
- (void)removeObjectForKey:(id)aKey; | |
- (void)removeAllObjects; | |
- (NSArray *)allKeys; | |
- (NSArray *)allValues; | |
- (void)enumerateKeysAndObjectsUsingBlock:(void (^)(id key, id obj, BOOL *stop))block; | |
- (void)enumerateKeysUsingBlock:(void (^)(id key, NSUInteger idx, BOOL *stop))block; | |
- (void)enumerateObjectsUsingBlock:(void (^)(id obj, NSUInteger idx, BOOL *stop))block; | |
- (BOOL)isEqualToOrderedDictionary:(OrderedDictionary *)orderedDictionary; | |
@end | |
// | |
// OrderedDictionary.m | |
// OrderedDictionary | |
// | |
// Created by Ayal Spitz on 3/25/13. | |
// Copyright (c) 2013 Ayal Spitz. All rights reserved. | |
// | |
#import "OrderedDictionary.h" | |
@implementation OrderedDictionary | |
- (id)init{ | |
self = [super init]; | |
if (self) { | |
_dictionary = [NSMutableDictionary dictionary]; | |
_array = [NSMutableArray array]; | |
} | |
return self; | |
} | |
- (id)initWithCapacity:(NSUInteger)capacity{ | |
self = [super init]; | |
if (self) { | |
_dictionary = [NSMutableDictionary dictionaryWithCapacity:capacity]; | |
_array = [NSMutableArray arrayWithCapacity:capacity]; | |
} | |
return self; | |
} | |
#pragma mark - | |
+ (id)dictionary{ | |
return [[OrderedDictionary alloc]init]; | |
} | |
+ (id)dictionaryWithCapacity:(NSUInteger)capacity{ | |
return [[OrderedDictionary alloc]initWithCapacity:capacity]; | |
} | |
#pragma mark - NSCopying methods | |
- (id)copyWithZone:(NSZone *)zone{ | |
OrderedDictionary *dictionary = [[OrderedDictionary alloc]initWithCapacity:self.count]; | |
dictionary->_dictionary = [self->_dictionary mutableCopyWithZone:zone]; | |
dictionary->_array = [self->_array mutableCopyWithZone:zone]; | |
return dictionary; | |
} | |
#pragma mark - NSCoding methods | |
#define kDictionaryKey @"Dictionary" | |
#define kArrayKey @"Array" | |
- (id)initWithCoder:(NSCoder *)decoder{ | |
self = [super init]; | |
if (self) { | |
_dictionary = [decoder decodeObjectForKey:kDictionaryKey]; | |
_array = [decoder decodeObjectForKey:kArrayKey]; | |
} | |
return self; | |
} | |
- (void)encodeWithCoder:(NSCoder *)encoder{ | |
[encoder encodeObject:_dictionary forKey:kDictionaryKey]; | |
[encoder encodeObject:_array forKey:kArrayKey]; | |
} | |
#pragma mark - Set methods | |
- (void)setObject:(id)object forKeyedSubscript:(id<NSCopying>)aKey{ | |
id value = _dictionary[aKey]; | |
if (object != nil){ | |
// if value isn't nil that means we are changing a key/value so we're changing it's index | |
if (value != nil){ | |
[_array removeObject:aKey]; | |
} | |
[_array addObject:aKey]; | |
_dictionary[aKey] = object; | |
} else { | |
[_array removeObject:aKey]; | |
[_dictionary removeObjectForKey:aKey]; | |
} | |
} | |
#pragma mark - Get Methods | |
- (id)objectForKeyedSubscript:(id)key{ | |
return _dictionary[key]; | |
} | |
- (id)objectAtIndexedSubscript:(NSUInteger)idx{ | |
return self[_array[idx]]; | |
} | |
#pragma mark - Remove Methods | |
- (void)removeObjectForKey:(id)aKey{ | |
self[aKey] = nil; | |
} | |
- (void)removeAllObjects{ | |
[_dictionary removeAllObjects]; | |
[_array removeAllObjects]; | |
} | |
#pragma mark - | |
- (NSUInteger)count{ | |
return _dictionary.count; | |
} | |
#pragma mark - Keys and Objects methods | |
- (NSArray *)allKeys{ | |
return [_array copy]; | |
} | |
- (NSArray *)allValues{ | |
NSMutableArray *objects = [NSMutableArray arrayWithCapacity:_array.count]; | |
[_array enumerateObjectsUsingBlock:^(id key, NSUInteger idx, BOOL *stop) { | |
[objects addObject:self[key]]; | |
}]; | |
return objects; | |
} | |
- (void)enumerateKeysAndObjectsUsingBlock:(void (^)(id key, id obj, BOOL *stop))block{ | |
[_array enumerateObjectsUsingBlock:^(id key, NSUInteger idx, BOOL *stop) { | |
id obj = self[key]; | |
block(key, obj, stop); | |
}]; | |
} | |
- (void)enumerateKeysUsingBlock:(void (^)(id key, NSUInteger idx, BOOL *stop))block{ | |
[_array enumerateObjectsUsingBlock:^(id key, NSUInteger idx, BOOL *stop) { | |
block(key, idx, stop); | |
}]; | |
} | |
- (void)enumerateObjectsUsingBlock:(void (^)(id obj, NSUInteger idx, BOOL *stop))block{ | |
[_array enumerateObjectsUsingBlock:^(id key, NSUInteger idx, BOOL *stop) { | |
id obj = self[key]; | |
block(obj, idx, stop); | |
}]; | |
} | |
#pragma mark - Equality methods | |
- (BOOL)isEqualToOrderedDictionary:(OrderedDictionary *)orderedDictionary{ | |
return ([self.allKeys isEqualToArray:orderedDictionary.allKeys] && [self.allValues isEqualToArray:orderedDictionary.allValues]); | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment