Как я могу получить оригинальный порядок NSDictionary / NSMutableDictionary? - PullRequest
10 голосов
/ 02 августа 2010

Я создал NSMutableDictionary с 10 ключами. Теперь я хочу получить доступ к ключам NSMutableDictionary в том же порядке, как он был добавлен в NSMutableDictionary (используя SetValue: * forKey: *);

Как я могу этого достичь?

Ответы [ 5 ]

9 голосов
/ 02 августа 2010

Если вам абсолютно необходимо использовать контейнер словаря, вы должны использовать ключ, который сортируется по порядку, в котором вы добавляете пары ключ-значение. Таким образом, при создании словаря вы используете ключ, который представляет собой автоматически увеличивающееся целое число или аналогичный. Затем вы можете сортировать по (целочисленным) ключам и получать значения, связанные с этими ключами.

Однако, если вы все это сделаете, вы можете просто использовать NSMutableArray и добавлять значения в массив напрямую! Это будет намного быстрее и потребует меньше кода. Вы просто получаете объекты по порядку:

for (id obj in myArray) { /* do stuff with obj... */ }
7 голосов
/ 02 августа 2010

NSMutableDictionary не может этого сделать.Взгляните, например, на Мэтта Галлахера OrderedDictionary.

2 голосов
/ 18 декабря 2013

Я написал быстрый метод, чтобы взять исходный массив (из объектов, которые все не в порядке) и ссылочный массив (который имеет объекты в желаемом (и совершенно произвольном) порядке), и возвращает массив, в котором элементы исходный массив был реорганизован для соответствия эталонному массиву.

- (NSArray *) reorderArray:(NSArray *)sourceArray toArray:(NSArray *)referenceArray
{
    NSMutableArray *returnArray = [[NSMutableArray alloc] init];
    for (int i = 0; i < [referenceArray count]; i++)
    {
        if ([sourceArray containsObject:[referenceArray objectAtIndex:i]])
        {
            [returnArray addObject:[arrReference objectAtIndex:i]];
        }
    }
    return [returnArray copy];
}

Обратите внимание, что это очень хрупко. Он использует NSArray containsObject: метод, который в конечном итоге вызовет NSObject '* isEqual:. По сути, он должен отлично работать для массивов NSString s, NSNumber s и, возможно, NSDate s (еще не пробовал), но вне этого, YMMV. Я полагаю, если бы вы попытались передать массивы UITableViewCell s или какой-либо другой действительно сложный объект, он бы полностью сам себя закинул и либо вылетел, либо возвратил полный мусор. Точно так же, если вам нужно сделать что-то вроде передачи массива NSDate с в качестве ссылочного массива и массива NSString с в качестве исходного массива. Кроме того, если исходный массив содержит элементы, не включенные в ссылочный массив, они просто будут удалены. Можно решить некоторые из этих проблем, добавив немного дополнительного кода.

Все это говорит, что если вы пытаетесь сделать что-то простое, это должно работать хорошо. В вашем случае вы могли бы создать массив ссылок, когда вы просматриваете ваш setValue:forKey:.

NSMutableArray *referenceArray = [[NSMutableArray alloc] init];
NSMutableDictionary *yourDictionary = [[ NSMutableDictionary alloc] init];

for (//whatever you are looping through here)
{

    [yourDictionary setValue://whatever forKey:key];
    [referenceArray addObject:key];

}

Затем, когда вы хотите перебрать свои предметы в порядке их поступления, вы просто

for (NSString *key in [self reorderArray:[myDict allKeys] toArray:referenceArray])
0 голосов
/ 04 октября 2015

Хотя ответ @GenralMike работает на одном дыхании, его можно оптимизировать, исключив ненужный код следующим образом:

1) Сохранить массив для хранения ссылки на ключи словаря в порядке их добавления.

NSMutableArray *referenceArray = [[NSMutableArray alloc] init];
NSMutableDictionary *yourDictionary = [[ NSMutableDictionary alloc] init];

for (id object in someArray) {

     [yourDictionary setObject:object forKey:someKey];
     [referenceArray addObject:someKey]; // add key to reference array

}

2) Теперь "referenceArray" хранит все ключи по порядку, поэтому вы можете извлекать объекты из словаря в том же порядке, в котором они были первоначально добавлены в словарь.

for (NSString *key in referenceArray){
    //get object from dictionary in order
    id object = [yourDictionary objectForKey:key];
}
0 голосов
/ 25 июля 2014

На самом деле у вас есть ссылочный массив по порядку, тогда почему вы должны добавить еще один массив. Так что я думаю, что этот подход не очень хорош. Пожалуйста, примите во внимание мое мнение.

...