Сортировка NSArray с помощью NSDictionary

Я использую NSSortDiscriptors для сортировки NSArray. Каждый индекс в массиве содержит словарь с записями ключей и значений. Этот словарь также содержит другой словарь.

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

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

- (void)sortArray {

if ([array count] != 0) {

    // Reports sortingDescriptors
    NSSortDescriptor * city = [[NSSortDescriptor alloc] initWithKey:@"City" ascending:YES];
    NSSortDescriptor * name = [[NSSortDescriptor alloc] initWithKey:@"Name" ascending:YES];
    NSSortDescriptor * country = [[NSSortDescriptor alloc] initWithKey:@"Country" ascending:YES];

    [reportsArray sortUsingDescriptors:[NSArray arrayWithObjects:city, name, country, nil]];

    [name release];
    [city release];
    [country release];
}
}

Массив выглядит так:

[{name = "";
city = "";
country = "";
date = {
 dateAdded = "";
 dateRemoved = "";
}
}];

Поэтому я также хочу отсортировать, например, если есть значение на dateAdded.


person Silversnail    schedule 06.07.2011    source источник


Ответы (3)


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

person JustSid    schedule 06.07.2011

Возможно, вы захотите проверить, содержит ли словарь такое значение:

// you can't set nil as a value for a key
if([yourDictionary objectForKey:@"yourKey"] == [NSNull null]) { ... }

Затем вам нужно отсортировать оставшиеся объекты, но словарь, для этого сделайте копию вашего массива без записи словаря, выполнив что-то вроде:

NSMutableArray *tmpArray = [NSMutableArray arrayWithArray:firstArray];
[tmpArray removeObjectAtIndex:theIndexOfTheDictionary];
// sort your array, don't forget to catch the returned value
NSMutableArray *sortedArray = [tmpArray sortUsingDescriptors:[NSArray arrayWithObjects:city, name, country, nil]];
// finally, put the dictionary back in (if needed)
[sortedArray insertObject:theDictionary atIndex:theIndexYouWant];
person Community    schedule 06.07.2011

Вы говорите, что объекты в массиве имеют свойства City, Name и Country, а также свойство словаря, и вы хотите отсортировать по одному из ключей в словаре? Или вы говорите, что записи в массиве являются словарями, но иногда ключ города, имени или страны отсутствует? Или вы говорите, что некоторые записи являются словарями, а некоторые — объектами с перечисленными свойствами?

В любом случае вы можете добиться большей гибкости, создав дескриптор сортировки с помощью initWithKey:ascending:comparator:. Это позволяет вам использовать блок компаратора в качестве функции сортировки, которая является более гибкой, чем прямой селектор, например.

NSComparator mySort = ^(id obj1, id obj2)
{
    NSComparisonResult ret = NSOrderedSame;

    if ([obj1 isKindOfClass: [NSDictionary class]] && ![obj2 isKindOfClass: NSDictionary class]])
    {
        ret = NSOrderedAscending;
    }
    else if (![obj1 isKindOfClass: [NSDictionary class]] && [obj2 isKindOfClass: NSDictionary class]])
    {
        ret = NSOrderedDescending;
    }
    return ret;
};
NSSortDescriptor* descriptor = [[NSSortDescriptor alloc] initWithKey: @"self" ascending: YES comparator: mySort];

даст вам дескриптор сортировки, который сортирует массив, помещая сначала все NSDictionaries, а затем другие объекты. (self — это ключ, которым обладают все NSObject, который возвращает сам объект).

person JeremyP    schedule 06.07.2011
comment
Вы говорите, что объекты в массиве имеют свойства City, Name и Country, а также свойство словаря, и вы хотите отсортировать по одному из ключей в словаре? да. Сортировка должна быть по одному свойству словаря, а также по свойствам City, Name, Country. - person Silversnail; 06.07.2011
comment
Хорошо, нашел решение, которое сработало для меня. NSSortDescriptor * date = [[NSSortDescriptor alloc] initWithKey:@Date.time по возрастанию: НЕТ]; Здесь Date - это словарь, который содержит ключевое время, которое я использую для сортировки массива вместе с другими NSSortDescriptors выше. - person Silversnail; 06.07.2011