Getting NSDictionary key by index?

ios, ios7, nsdictionary, objective-c, uipickerview

Solution

Since `NSDictionary` is an unordered associative container, it has no concept of indexing. Its keys are ordered arbitrarily, and that order can change in the future.

You can get an `NSArray` of keys from the dictionary, and apply indexing to it:

NSArray *keys = [myDict allKeys]; // Warning: this order may change.

However, this indexing scheme would remain consistent only as long as the dictionary remains unchanged: for example, if you use `NSMutableDictionary`, adding an extra key may change the ordering of the existing keys. This leads to extremely hard-to-debug problems.

A better approach would be to place the items for your picker into an ordered container, such as `NSArray`. Create a special class for the picker items, for example

@interface MyPickerItem : NSObject
@property (readwrite, nonatomic) NSString *item1;
@property (readwrite, nonatomic) NSString *item2;
@end

create an `NSArray` of such `MyPickerItem` objects from your dictionary, order them the way you want them to appear in the picker view (say, alphabetically by `item1`, then by `item2`) and use `NSArray` as the data source for your picker view:

- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
    MyPickerItem *p = myArray[row];
    switch (component) {
        case 0: return p.item1;
        case 1: return p.item2;
    }
    return @"<-ERROR->";
}

Problem

Is it possible to get a dictionary key by index? I'm trying to use a dictionary for the datasource of a picker view and want to access it in following delegate method: ``` - (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component{ if (component == 0){ return [NSString stringWithFormat:@"%@",[myDict // how to get the key]]; } ``` EDIT-- myDict is something like: Item 1 - sub item 1 - sub item 2 Item 2 - sub item 1 - sub item 2 I want to use myDict as the datasource for a picker view that has 2 sections: section 0 = myDict keys (Item 1, Item 2) section 1 = corresponding myDict values for selected section 0 row (sub item 1, sub item 2)

Original source