Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bidirectional Map in Cocoa

Cocoa provides NSDictionary, which essentially is an associative array.

Is there a nice way to get bidirectional associativity? i.e. one way would have been if NSDictionary had a keyForObject: method which mirrored the behavior of objectForKey:.

I don't really care if NSDictionary is not the way to get this. I know NSDictionary does provide keysOfEntriesPassingTest: but it returns an NSSet * which doesn't look very clean for the kind of thing I want to have.

Here is an example:

fieldMap = [[NSDictionary alloc] initWithObjectsAndKeys:
    @"c0",@"synckey",
    @"c1",@"wi_id",
    @"c2",@"wi_parent_id",
    @"c3",@"wi_type",
    @"c4",@"wi_rh_task",
    @"c5",@"decision_key",
    @"c6",@"wi_stat",
    @"c7",@"wi_prio",
    @"c8",@"wi_cd",
    @"c9",@"wi_ct",
    @"cb",@"wi_dh_stat",
    @"cc",@"wi_user",
    nil];

I want to translate between c0 and synckey and back, and ditto for the other fields.

like image 465
ArjunShankar Avatar asked Mar 10 '10 11:03

ArjunShankar


1 Answers

The closest thing for what you're after is, I believe allKeysForObject:. This returns an NSArray containing the keys corresponding to all occurrences of a given object in the dictionary. Obviously if the object is in the dictionary only once, the NSArray will contain only one object.

So with your example:

fieldMap = [[NSDictionary alloc] initWithObjectsAndKeys:
    @"c0",@"synckey",
    @"c1",@"wi_id",
    @"c2",@"wi_parent_id",
    @"c3",@"wi_type",
    @"c4",@"wi_rh_task",
    @"c5",@"decision_key",
    @"c6",@"wi_stat",
    @"c7",@"wi_prio",
    @"c8",@"wi_cd",
    @"c9",@"wi_ct",
    @"cb",@"wi_dh_stat",
    @"cc",@"wi_user",
    nil];

This additional code would return an array containing 1 string object evaluating to @"c7":

NSArray *keyArray = [fieldMap allKeysForObject:@"wi_prio"];

[Aside: Note that this would only work here because of how the compiler works; it takes all occurences of @"wi_prio" and makes them the same object. If instead you had perhaps loaded the dictionary from disk etc, this approach will not work for NSStrings. Instead you should probably use allKeys and then iterate through them, comparing with [mystring isEqualToString:anotherString].]

like image 176
h4xxr Avatar answered Nov 03 '22 00:11

h4xxr