NSMutableDictionary переупорядочивает элементы после вставки

Возможный дубликат:
NSDictionary с упорядоченными ключами

Я использую XMPPFramework для iOS и весьма удивлен, увидев, что NSDictionary, содержащий агентов комнаты, изменяет порядок своего содержимого каждый раз, когда вставляется новый агент / элемент.

Вот результат после каждой вставки.

<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>
}

Как вы можете видеть в этой последней вставке, он изменил порядок двух элементов, он также изменил свой индекс. Это нормально? Я посмотрел на код и его вставку, используя:

[агенты setObject: агент forKey: aNickName];

Мне нужно, чтобы элементы сохранялись в том порядке, в котором они были вставлены. И мне также нужно получить доступ к элементу через строку. Любая идея?

Спасибо


person subharb    schedule 20.04.2012    source источник


Ответы (3)


NSDictionary не подготовлен для размещения какого-либо порядка, подготовлен для содержания пар ключ-объект, если вы хотите сохранить порядок, вам нужно другое решение, например NSArray для него.

Может быть, вам нужно переосмыслить свою реализацию!

person Antonio MG    schedule 20.04.2012

Я думаю, что NSDictionary не помнит, как были вставлены пары ключ-значение. Вы можете отсортировать ключи или значения примерно по sortedArrayUsingSelector:, но если порядок важен, вместо этого следует использовать NSArray.

person Hailei    schedule 20.04.2012

Вам не следует беспокоиться о порядке, в котором ключи хранятся внутри NSDictionary, поскольку это карта, в которой нет порядка. Вам действительно важен порядок, в котором вы извлекаете значения, поэтому вам нужно отсортировать ключи и получить доступ к значениям в отсортированном порядке.

Вот пример сортировки ключей по алфавиту и получения значений по порядку:

NSArray *sortedKeys =[[dict allKeys] sortedArrayUsingSelector:@selector(compare:)];
for (NSString *key in sortedKeys)
{
    NSString *value = [dict objectWithKey:key];
}
person trojanfoe    schedule 20.04.2012
comment
Дело в том, что каждый раз, когда вставляется элемент, я использую словарь для печати данных, поэтому, поскольку порядок изменения уже напечатанных данных не имеет смысла ... - person subharb; 20.04.2012
comment
@DavidShaikh Похоже, вы хотите определить порядок печатаемых данных, поэтому вам нужно отсортировать ключи, как описано. - person trojanfoe; 20.04.2012
comment
Но порядок, который мне нужно сохранить, - это то, как он был вставлен, а не в алфавитном порядке, который, как мне кажется, сохраняется. Первый элемент вставлен, и я печатаю первый элемент. Вставлен еще один элемент, и я распечатываю второй, но, к сожалению, порядок изменился, и я фактически печатаю первый элемент во второй раз. - person subharb; 20.04.2012
comment
@DavidShaikh Хорошо, тогда вам нужно сохранить отдельный NSArray, который содержит только ключи в том порядке, в котором они были вставлены, и это может действовать как sortedKeys выше. - person trojanfoe; 20.04.2012
comment
Мне также нужно было бы удалить данный элемент из массива, есть ли самый быстрый способ вместо того, чтобы проходить через весь массив? то же самое, что и nsdictionary removeObject с ключом. - person subharb; 20.04.2012
comment
@DavidShaikh Вы можете написать класс, который инкапсулирует как NSArray, так и NSDictionary и имеет тот же интерфейс, что и NSDictionary; как только это будет сделано, вы даже не узнаете, что это не NSDictionary. - person trojanfoe; 20.04.2012