-2

I saw many examples on SO but I'm not sure if it applies to this situation. Everywhere it says NSMutableDictionries are not guaranteed an order...but I'm getting my data from the server...so my NSMuteDic looks like this:

{
joe =     (
            {
        fromName = joe;
        id = 25;
        theMessage = "this is going to be a really big message...";
        timeAdded = "2014-04-07 21:08:12";
        toName = "me";
    },
            {
        fromName = joe;
        id = 10;
        theMessage = "why???";
        timeAdded = "2014-04-05 20:10:04";
        toName = "me";
    }
);
bob =     (
            {
        fromName = "me";
        id = 24;
        theMessage = "blah blah";
        timeAdded = "2014-04-06 21:15:06";
        toName = bob;
    },
            {
        fromName = bob;
        id = 22;
        theMessage = message;
        timeAdded = "2014-04-06 20:11:57";
        toName = "me";
    }
);
//more entries here
}

What I want to do is change the order...put bob first and joe second. Is this really impossible to do? I saw many very complex solutions...there's no easy way to do this with just a for loop?

cellForRowAtIndexPath: NSMutableArray *temp = [myDict objectForKey:keys[indexPath.row]]; cell.Message.text = [[reverse lastObject] valueForKey:@"theMessage"]; cell.dateTime.text = [[reverse lastObject] valueForKey:@"timeAdded"]; return cell;

This is how I'm using it...and when a row is selected I pass the array to the next view controller. The reason why I want to reorder is if a new message will be inserted in the pushed view controller, I want that dictionary to be first in the list so the root view controller can be reordered.

NSArray *keys = [myDict allKeys];
[myDict removeObjectForKey:to];
NSMutableDictionary *temp = [NSMutableDictionary dictionaryWithCapacity:[myDict.count];
temp = myDict;
[myDict removeAllObjects];
[myDict setObject:currentDict forKey:to];
for (int i=0; i<temp.count; i++) {
    [myDict setObject:[temp valueForKey:keys[i]] forKey:keys[i]];
}

That's not working because it looks like since myDict is a NSObject, temp gets changed every time myDict changes...from the looks of it the logic should work but it isn't...

denikov
  • 877
  • 2
  • 17
  • 35
  • The way everything is set up, this is how I access the information for my table view. This is how the data comes back from the server $messages[$row['from']] = $row; – denikov Apr 10 '14 at 18:49
  • I saw that post but none of the answers there look like my set up. Or am I not understanding something? – denikov Apr 10 '14 at 18:52
  • An NSDictionary is a non-ordered object, so it's impossible to do if you're sticking with NSDictionary. How do you want to use the dictionary? You can certainly sort the keys if you're using it in a table view . – rdelmar Apr 10 '14 at 18:59
  • I added more information of how I'm using it and why I want to reorder it eventually. – denikov Apr 10 '14 at 19:07
  • Not entirely clear how you want to order the dictionary. If you want to address it's items alpabetically (by key), then you could store `allKeys` in an array and sort that one. Iterate over that array and get the items by key. – fguchelaar Apr 10 '14 at 19:39
  • That's what I'm working on right now...trying to reorder by using valueForKey:keys[iterator]. If you have an example to make my life easier, I wouldn't be against seeing it :) – denikov Apr 10 '14 at 19:49
  • Just create a sorted array like this, NSArray *sortedArray = [myDict.allKeys sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)]; – rdelmar Apr 10 '14 at 20:10
  • Thanks. I have that part. What I'm struggling with is the sorting of it. myDict is an NSObject so what I'm trying to do is make a copy of the dictionary without the object which I want first, insert the first object back into myDict, and then iterate over the copy inserting into myDict. It's not working – denikov Apr 10 '14 at 20:15
  • What it looks like is since myDict is an NSObject, when it changes, the temporary dictionary changes as well. – denikov Apr 10 '14 at 20:17
  • There is no "first object" in a dictionary, so I don't know what you mean. What you need to do is further describe what you mean by this, "I want to reorder is if a new message will be inserted in the pushed view controller, I want that dictionary to be first in the list so the root view controller can be reordered." What do you want the table view in the first controller to look like at start up? What do you want it to look like after a new message is added? It's not clear what you're even displaying in the table view. – rdelmar Apr 10 '14 at 20:32
  • The root view controller table will have the latest message as row one. In the pushed view controller, if a user enters a message, I want to reorder the dictionary so that user is the first one, making the root view controller updated with the latest message. Does that make sense? But apparently that will not work because the dictionary does not keep the order... – denikov Apr 10 '14 at 20:55

2 Answers2

3

NSMutableDictionary is not ordered. There is nothing you can do to guarantee the order of keys because NSDictionary makes no attempt to preserve any particular ordering. To go over a dictionary in a particular order, you have to make an array of the keys that is in the order you want, then iterate that and fetch the corresponding values.

Chuck
  • 234,037
  • 30
  • 302
  • 389
0
// Get the keys
NSArray *keys = [myDict allKeys];

// Sort the keys
NSArray *sortedArray = [NSArray arrayWithArray:[keys sortedArrayUsingComparator:^(NSString* a, NSString* b) {
    return [a compare:b];
}]];

// Iterate the dictionary
for (NSUInteger n = 0 ; < [sortedArray count]; n++) {
    id value = [myDict objectForKey:[sortedArray objectAtIndex:n]];

}
Leonardo Bernardini
  • 1,076
  • 13
  • 23
  • That looks like it could work but...I'm still learning and I don't understand sortedArrayUsingComparator. If I have 3 different strings, or n number of strings...how would I use this function? – denikov Apr 10 '14 at 22:29