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
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)
This will give you randomly ordered keys
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component{
if (component == 0){
return [NSString stringWithFormat:@"%@",[myDict allKeys][row]];
}
}
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->";
}
No, as a dictionary doesn't have order.
You'll need to provide an array of keys, which will give you your order, in addition to the dictionary.
@interface MyClass ()
@property NSMutableArray *keysArray; // Don't forget to allocate this in an init method
@end
- (NSString *)pickerView:(UIPickerView *)pickerView
titleForRow:(NSInteger)row
forComponent:(NSInteger)component
{
if (component == 0){
NSString *key = self.keysArray[row];
return self.myDict[key]; // I assume you just want to return the value
}
...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With