12

as the title, when I insert element to a dictionary in objective-c (in order like: k1, k2, k3), is there any guarantee that when I enumerate it like:

for ( k in dictionary ){
   // output the k - value
}

it would show in the same order?

warren
  • 32,620
  • 21
  • 85
  • 124
fallhunter
  • 551
  • 1
  • 9
  • 16

5 Answers5

21

No, NSDictionary does not maintain the insertion order of its keys.

If you need a dictionary that maintains insertion order, I'd suggest using the CHDataStructures framework, which has a CHOrderedDictionary class (it's a descendent of NSMutableDictionary). The documentation for CHOrderedDictionary says:

A dictionary which enumerates keys in the order in which they are inserted.

The following additional operations are provided to take advantage of the ordering:

-firstKey

-lastKey

-keyAtIndex:

-reverseKeyEnumerator

Key-value entries are inserted just as in a normal dictionary, including replacement of values for existing keys, as detailed in -setObject:forKey:. However, an additional structure is used in parallel to track insertion order, and keys are enumerated in that order. If a key to be added does not currently exist in the dictionary, it is added to the end of the list, otherwise the insertion order of the key does not change.

Dave DeLong
  • 242,470
  • 58
  • 448
  • 498
12

NSDictionary's keys aren't kept in order, but you can get them and sort them, E. G:

for (key in [[myDict allKeys] sortedArrayUsingSelector:@selector(compare:)])
...
NSResponder
  • 16,861
  • 7
  • 32
  • 46
  • 1
    Quick and easy, thanks. But does the application have to perform the sorting operation each time it iterates through the loop? If so, I would do the sort once and put that result into a variable, then iterate over the variable. – arlomedia Jul 16 '11 at 00:14
  • 2
    @arlomedia No, the for loop evaluates the collection expression first, then iterates over the result. So the sorting only happens once in this example. – Rik Smith-Unna Mar 23 '12 at 19:11
  • 1
    the question asks for ordered (in insertion order), not sorted – user102008 May 04 '12 at 20:52
  • Although it does not provide in insertion order but it provides the indexed order. Solves my issue anyways. – Abdul Jamil Aug 23 '17 at 18:18
5

Something I'd like to add in case someone is searching for this and stumbles on this thread:

There's a rather easy work-around for ordered dictionaries, and that's having an Array, which contains the keys in the order you want. Then having an unordered dictionary, but you can access each key in order using the keys from the array:

NSString *key = [arrayOfKeys objectAtIndex:0];
NSString *stringAtIndexZero = [unorderedDictionary objectForKey:key];
Lord Zsolt
  • 6,492
  • 9
  • 46
  • 76
4

No, it is not ordered. You can use an array of keys to remember an order if you need to, but dictionaries are conceptually unordered bags of key-value pairs.

Chuck
  • 234,037
  • 30
  • 302
  • 389
0

I've also seen this one when searching for this: http://cocoawithlove.com/2008/12/ordereddictionary-subclassing-cocoa.html

Rafael Sanches
  • 1,823
  • 21
  • 28