How can i get Original order of NSDictionary/NSMutableDictionary?
Asked Answered
F

5

10

i have created NSMutableDictionary with 10 keys.Now i want to access NSMutableDictionary keys in a same order as it was added to NSMutableDictionary (using SetValue:* forKey:* );

How can i achieve that ?

Frydman answered 2/8, 2010 at 10:36 Comment(1)
The keys are not fixed, they are dynamic.Frydman
H
9

If you absolutely must use a dictionary container, you have to use a key that is sortable by the order in which you add key-value pairs. Thus, when creating your dictionary, you use a key that is an auto-incrementing integer or similar. You can then sort on the (integer) keys and retrieve the values associated with those keys.

If you do all of that, however, you may as well just use an NSMutableArray and add values to the array directly! It will be much faster and require less code. You just retrieve objects in order:

for (id obj in myArray) { /* do stuff with obj... */ }
Heiney answered 2/8, 2010 at 10:42 Comment(0)
K
7

NSMutableDictionary can't do that. Take a look at e.g. Matt Gallaghers OrderedDictionary.

Kwh answered 2/8, 2010 at 10:41 Comment(1)
But can u tell me how to use this Class?Benge
G
2

I wrote a quick method to take a source array (of objects that are all out of order) and a reference array (that has objects in a desired (and totally arbitrary) order), and returns an array where the items of the source array have been reorganized to match the reference array.

- (NSArray *) reorderArray:(NSArray *)sourceArray toArray:(NSArray *)referenceArray
{
    NSMutableArray *returnArray = [[NSMutableArray alloc] init];
    for (int i = 0; i < [referenceArray count]; i++)
    {
        if ([sourceArray containsObject:[referenceArray objectAtIndex:i]])
        {
            [returnArray addObject:[arrReference objectAtIndex:i]];
        }
    }
    return [returnArray copy];
}

Note that this is very fragile. It uses NSArray's containsObject: method, which ultimately will call NSObject's isEqual:. Basically, it should work great for arrays of NSStrings, NSNumbers, and maybe NSDates (haven't tried that one yet), but outside of that, YMMV. I imagine if you tried to pass arrays of UITableViewCells or some other really complex object, it would totally sh*t itself, and either crash or return total garbage. Likewise if you were to do something like pass an array of NSDates as the reference array and an array of NSStrings as the source array. Also, if the source array contains items not covered in the reference array, they'll just get discarded. One could address some of these issues by adding a little extra code.

All that said, if you're trying to do something simple, it should work nicely. In your case, you could build up the reference array as you are looping through your setValue:forKey:.

NSMutableArray *referenceArray = [[NSMutableArray alloc] init];
NSMutableDictionary *yourDictionary = [[ NSMutableDictionary alloc] init];

for (//whatever you are looping through here)
{

    [yourDictionary setValue://whatever forKey:key];
    [referenceArray addObject:key];

}

Then, when you want to loop over your items in the order they came in, you just

for (NSString *key in [self reorderArray:[myDict allKeys] toArray:referenceArray])
Gilbertgilberta answered 17/12, 2013 at 20:38 Comment(1)
Needless to use the first piece of code in your answer above. Once you have set the keys in the reference array as you do above where you set key in the referenceArray, you no longer need to mess with the "source-reference" array method (first method above) because an array holds values in "ORDER". You can simply iterate over the referenceArray and get the objects from "yourDictionary" in order just as "Ganesh" pointed out in the post below: for (NSString *key in referenceArray){ //get object from dictionary id object = [yourDictionary objectForKey:key]; }Marxism
C
0

Actually you have a reference array in order manner then why you have to add to one more array.So i guess this approach is not good.Please consider my opinion.

Complacence answered 25/7, 2014 at 11:10 Comment(0)
M
0

Although @GenralMike 's answer works a breeze, it could be optimized by leaving off the unnecessary code as follows:

1) Keep an array to hold reference to the dictionary keys in the order they are added.

NSMutableArray *referenceArray = [[NSMutableArray alloc] init];
NSMutableDictionary *yourDictionary = [[ NSMutableDictionary alloc] init];

for (id object in someArray) {

     [yourDictionary setObject:object forKey:someKey];
     [referenceArray addObject:someKey]; // add key to reference array

}

2) Now the "referenceArray" holds all of the keys in order, So you can retrieve objects from your dictionary in the same order as they were originally added to the dictionary.

for (NSString *key in referenceArray){
    //get object from dictionary in order
    id object = [yourDictionary objectForKey:key];
}
Marxism answered 4/10, 2015 at 6:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.