Сортировать NSArray с NSDictionary - PullRequest
1 голос
/ 06 июля 2011

Я использую 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, например.

Ответы [ 4 ]

1 голос
/ 06 июля 2011

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

0 голосов
/ 01 марта 2012
NSArray *unsortedArray=[NSArray arrayWithObjects:[NSDictionary dictionaryWithObjectsAndKeys:@"anil",@"personInDictionary.lastName" ,nil],[NSDictionary dictionaryWithObjectsAndKeys:@"aneelu",@"personInDictionary.lastName", nil] ,[NSDictionary dictionaryWithObjectsAndKeys:@"kumar",@"anil.lastName", nil] ,nil];

 NSSortDescriptor * descriptor = [[[NSSortDescriptor alloc] initWithKey:@"personInDictionary.lastName"             ascending:YES] autorelease]; // 1

  NSArray * sortedArray = [unsortedArray sortedArrayUsingDescriptors:
                             [NSArray arrayWithObject:descriptor]];

 NSLog(@"sortedArray values %@",sortedArray);

  for (id object in [sortedArray valueForKey:@"personInDictionary.lastName"]) {

        NSLog(@"sortedArray value %@",object);
    }
0 голосов
/ 06 июля 2011

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

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

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 s, который возвращает сам объект).

0 голосов
/ 06 июля 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];
...