1

Possible Duplicate:
NSDictionary with ordered keys

Im using XMPPFramework for iOS, and Im quite suprised seing that a NSDictionary containing the occupants of a room changes the order of its content every time a new occupant/element is inserted.

Here's the output, after each insert.

<CFBasicHash 0xbccbd60 [0x1f02400]>{type = mutable dict, count = 2,entries =>
1 : <CFString 0xbcd90b0 [0x1f02400]>{contents = "4ee90610e4b08c62894a648c"} = <XMPPRoomOccupant: 0xbcd9360>
2 : <CFString 0xbe5a160 [0x1f02400]>{contents = "4eea53a6e4b08c62894a6c90"} =     <XMPPRoomOccupant: 0xbca7cc0>
}

<CFBasicHash 0xbccbd60 [0x1f02400]>{type = mutable dict, count = 3,entries =>
0 : <CFString 0xbe60710 [0x1f02400]>{contents = "4ee8fca3e4b08c62894a6489"} = <XMPPRoomOccupant: 0xbe61370>
1 : <CFString 0xbcd90b0 [0x1f02400]>{contents = "4ee90610e4b08c62894a648c"} = <XMPPRoomOccupant: 0xbcd9360>
2 : <CFString 0xbe5a160 [0x1f02400]>{contents = "4eea53a6e4b08c62894a6c90"} = <XMPPRoomOccupant: 0xbca7cc0>
}

<CFBasicHash 0xbccbd60 [0x1f02400]>{type = mutable dict, count = 4,entries =>
0 : <CFString 0xbe5a160 [0x1f02400]>{contents = "4eea53a6e4b08c62894a6c90"} = <XMPPRoomOccupant: 0xbca7cc0>
4 : <CFString 0xbe71eb0 [0x1f02400]>{contents = "4f7ade44e4b09cb64dc33b90"} = <XMPPRoomOccupant: 0xbe72950>
5 : <CFString 0xbe60710 [0x1f02400]>{contents = "4ee8fca3e4b08c62894a6489"} = <XMPPRoomOccupant: 0xbe61370>
6 : <CFString 0xbcd90b0 [0x1f02400]>{contents = "4ee90610e4b08c62894a648c"} = <XMPPRoomOccupant: 0xbcd9360>
}

AS you can see in this last insert it changed the order of 2 elements, it changed its index too. Is this normal? I looked at the code and its inserting using:

[occupants setObject:occupant forKey:aNickName];

I need the elements to be stored in the order it was inserted. And I also need to access the element through a string. Any idea?

Thanks

Community
  • 1
  • 1
subharb
  • 3,374
  • 8
  • 41
  • 72

3 Answers3

1

NSDictionary is not prepared to contain any order, is prepared for containing pairs of key-object, if you want to keep an order, you need a different solution, like a NSArray for it.

Maybe you need to re-think about your implementation!

Antonio MG
  • 20,382
  • 3
  • 43
  • 62
0

I think NSDictionary doesn't remember how the key-value pairs were inserted. You can sort the keys or values by something like sortedArrayUsingSelector:, but if order is important, one should use NSArray instead.

Hailei
  • 42,163
  • 6
  • 44
  • 69
0

You shouldn't worry about the order in which the keys are stored within the NSDictionary as it's a map, which has no order. You really care about the order in which you retrieve the values, so you have to sort the keys and access the values in the sorted order.

Here's an example of sorting the keys alphabetically, and retrieving the values in order:

NSArray *sortedKeys =[[dict allKeys] sortedArrayUsingSelector:@selector(compare:)];
for (NSString *key in sortedKeys)
{
    NSString *value = [dict objectWithKey:key];
}
trojanfoe
  • 120,358
  • 21
  • 212
  • 242
  • The thing is that each time an element is inserted I use the dictionary to print data, so since the order changes the already printed data doesnt make sense... – subharb Apr 20 '12 at 09:17
  • @DavidShaikh It sounds like you want to define the order of the printed data, so you need to sort the keys as described. – trojanfoe Apr 20 '12 at 09:18
  • But the order I need to keep is how it was inserted, not alphabetically, which I think is the one that is keeping The first element is inserted, and I print the first element. Another element is inserted, and I print the second one, but oops the order has changed and Im actually printing the first element for the second time. – subharb Apr 20 '12 at 09:27
  • @DavidShaikh OK, then you need to keep a separate `NSArray` which holds just the keys, in the order they were inserted, and this can act as `sortedKeys` above. – trojanfoe Apr 20 '12 at 09:34
  • I would also need to delete a given element from the array, is there a fastest way rather than going through the whole array? same thing as nsdictionary removeObject with key. – subharb Apr 20 '12 at 09:39
  • 1
    @DavidShaikh You could write a class which encapsulates both the `NSArray` and `NSDictionary` and has the same interface as `NSDictionary`; once that's done you wouldn't even know it wasn't an `NSDictionary`. – trojanfoe Apr 20 '12 at 09:47