views:

150

answers:

2

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.

+3  A: 

The CHDataStructures framework has CHBidirectionalDictionary.

Ole Begemann
CHDataStructures seems to have a lot of other stuff that is useful as well. I am going to go ahead and include it.
submachine
+2  A: 

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].]

h4xxr
That would be one way to do it. I did not know that the compiler actually uses the same object for all constant strings. Thanks!
submachine