5

I executed the following code NSLog(@"%@", arrData); and the output in the debugger was expected like so:

    "0." =     {
"first_name"="John"
    };

    "1." =     {
"first_name"="Florence"
    };

    "2." =     {
"first_name"="Melinda"
    };
    "3." =     {
"first_name"="Zack"
    };

I then executed this code:

for (NSDictionary *book in arrData)
{
        NSLog(@"%@ %@" , book, [[arrData objectForKey:book]  objectForKey:@"first_name"]);
}

And the output was like so:

2. Melinda
0. John
3. Zack
1. Florence

How do I make the for loop print the results in the same order as ? NSLog(@"%@", arrData);

John
  • 32,403
  • 80
  • 251
  • 422
  • 4
    You don't. Entries in an NSDictionary are unordered, and may not even be returned in the same order two times in a row. If you want them ordered, put the data in an array and sort it the way you want. (Hint: Retrieve the list of keys, sort them the way you want, then work through that list to retrieve the index values.) – Hot Licks Nov 15 '12 at 12:46
  • Here is your answer : http://stackoverflow.com/questions/8360100/nsmutabledictionary-different-print-from-console-and-code – Vipul Nov 15 '12 at 13:22
  • What Hot Licks said. You can't enumerate an unordered collection and expect to operate on the items in a specific order. @HotLicks you should put that as an answer. – Metabble Nov 15 '12 at 17:35

1 Answers1

8

A few things are going on here.

First let's understand what %@ means in NSLog. Many iOS/Cocoa developers incorrectly believe %@ is associated with NSString, it's not. From Apple's documentation:

Objective-C object, printed as the string returned by descriptionWithLocale:if available, or description otherwise. Also works with CFTypeRef objects, returning the result of the CFCopyDescription function.

So, %@ takes any Objective-C or CFTypeRef object. Since you are using a NSDictionary, %@ will print the output of description or descriptionWithLocale:(id)locale. So what does that do? Again, from Apple's documentation:

If each key in the dictionary is an NSString object, the entries are listed in ascending order by key, otherwise the order in which the entries are listed is undefined.

When using the for-in loop, aka Fast-Enumeration, the order of the objects is undefined, so that is why the output of the loop is not in order. If you wanted to print the contents of an NSDictionary in order, you'll have to emulate the behavior of the description method.

From this stackoverflow post:

NSArray *sortedKeys = [[dict allKeys] sortedArrayUsingSelector: @selector(compare:)];
NSMutableArray *sortedValues = [NSMutableArray array];
for (NSString *key in sortedKeys) {
    [sortedValues addObject: [dict objectForKey: key]];
}

I hope this clears things up.

Community
  • 1
  • 1
Stephen Melvin
  • 3,696
  • 2
  • 27
  • 40