patternMinor
BiDirectional Dictionary (and its Mutable friend can come too)
Viewed 0 times
cancometooitsanddictionaryfriendbidirectionalmutable
Problem
I've attempted to implement a 1-to-1 dictionary in Objective-C. I'm probably missing some convenient methods that one might commonly want to use.
These are both declared in the same
The goal here is to make the object familiar and feel very similar to an
BiDiDictionary.h
Immutable:
Mutable:
BiDiDictionary.m
Immutable:
```
@implementation BiDiDictionary {
@protected NSMutableDictionary *_keyValueDict;
@protected NSMutableDictionary *_valueKeyDict;
}
return [self initWithDictionary:nil];
}
self = [super init];
if (self) {
_keyValueDict = [NSMutableDictionary dictionary];
_valueKeyDict = [NSMutableDictionary dictionary];
for (id key in [dictionary allKeys]) {
if (!_keyValueDict[key]) {
id value = dictionary[key];
if (
These are both declared in the same
.h file and implemented in the same .m file. I think if much more code is added to either of these, splitting them into their own files would probably be preferred, but remaining in the same files allows me to hide some implementation details that I might not otherwise be able to hide.The goal here is to make the object familiar and feel very similar to an
NSDictionary (or NSMutableDictionary) but allow 1-to-1 mapping, so that for each key there is exactly one value, and for each value there is exactly one key.BiDiDictionary.h
Immutable:
@interface BiDiDictionary : NSObject
- (instancetype)init;
- (instancetype)initWithDictionary:(NSDictionary *)dictionary;
+ (instancetype)dictionary;
+ (instancetype)dictionaryWithDictionary:(NSDictionary *)dictionary;
- (id)objectForKey:(id)key;
- (id)keyForObject:(id)object;
@property (readonly) NSArray *allKeys;
@property (readonly) NSArray *allObjects;
@endMutable:
@interface BiDiMutableDictionary : BiDiDictionary
- (void)setObject:(id)object forKey:(id)key;
- (void)setKey:(id)key forObject:(id)object;
- (void)removeObjectForKey:(id)key;
- (void)removeKeyForObject:(id)object;
- (void)removeAllObjects;
@endBiDiDictionary.m
Immutable:
```
@implementation BiDiDictionary {
@protected NSMutableDictionary *_keyValueDict;
@protected NSMutableDictionary *_valueKeyDict;
}
- (instancetype)init {
return [self initWithDictionary:nil];
}
- (instancetype)initWithDictionary:(NSDictionary *)dictionary {
self = [super init];
if (self) {
_keyValueDict = [NSMutableDictionary dictionary];
_valueKeyDict = [NSMutableDictionary dictionary];
for (id key in [dictionary allKeys]) {
if (!_keyValueDict[key]) {
id value = dictionary[key];
if (
Solution
Overall, this seems like a very sensible and straightforward implementation. I don't have a lot to say, but I do have a few small question:
-
In
-
In
-
In
[-BiDiMutableDictionary setKey:forObject:] you catch the exception, do nothing with it, then re-throw it. This is exactly the same as not catching it. I'd just remove the @try/@catch block. - As @nhgrif points out, this sets the source of the exception to the spot where it was re-thrown, so it makes some sense. I guess I'd document that in the code since it's a non-obvious bit of information.-
In
[-BiDiMutableDictionary removeObjectForKey:], what's the purpose of checking if the key passed in supports `? If it doesn't, then the key isn't contained in the dictionary because you've ensured that keys that don't implement the protocol can't be added via the -set methods. If the key is contained in the dictionary, then you already know it implements the protocol. So there doesn't appear to me to be much point in checking in the -remove` method.Context
StackExchange Code Review Q#79506, answer score: 3
Revisions (0)
No revisions yet.