Сортировать NSMutableArray пользовательских объектов по алфавиту - PullRequest
0 голосов
/ 18 января 2012

У меня есть NSMutableArray пользовательских объектов. Пользовательский объект (класс тегов) имеет два свойства, определенных следующим образом:

@interface Tag : NSObject

@property (strong, nonatomic) NSString *tid;
@property (strong, nonatomic) NSString *name;

Итак, я хочу отсортировать NSMutableArray этих объектов Tag по имени тега - как мне это сделать?

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

Ответы [ 2 ]

4 голосов
/ 18 января 2012

Существует несколько способов сортировки изменяемого массива в цели c.

Самое простое, что я обнаружил, - это использование [NSMutableArray sortUsingFunction:] .

Дляв вашем примере, что-то вроде этого должно быть достаточно для функции сортировки

NSComparisonResult sortTagByName(Tag *tag1, Tag *tag2, void *ignore)
{
    return [tag1.name compare:tag2.name];
}

. Вот полный список источников, который вы можете использовать для своего решения:

#import <Foundation/Foundation.h>


@interface Tag : NSObject {

}

@property (strong, nonatomic) NSString *tid;
@property (strong, nonatomic) NSString *name;

@end

@implementation Tag 
@synthesize tid;
@synthesize name;


@end

NSComparisonResult sortTagByName(Tag *tag1, Tag *tag2, void *ignore)
{
    return [tag1.name compare:tag2.name];
}

@interface stackExDemo : NSObject

@end


@implementation stackExDemo

+(void) demo {

    NSMutableArray * array = [NSMutableArray array];

    // add your objects here


    [array sortUsingFunction:sortTagByName context:nil];

}

@end

Разбивая это на соответствующие компоненты:

Функция

NSComparisonResult sortTagByName(Tag *tag1, Tag *tag2, void *ignore)
{
    return [tag1.name compare:tag2.name];
}

Это просто простая функция C (т.е. не метод, поэтому вы ненет необходимости определять его внутри секции реализации какого-либо конкретного класса, однако обычно имеет смысл определять его в классе, к которому он применяется).

В приведенном выше примере я определил его после @end для тега, просто чтобы прояснить, что это не метод класса.

Параметр, который я назвал "ignore", является "контекстом" для сортировки.В этом случае нет контекста, поэтому мы будем игнорировать его значение.

Поскольку вы сортируете на основе свойства NSString, метод сравнения NSString удобен, однако вы также можете вручную вернуть один из {NSOrderedAscending,NSOrderedSame, NSOrderedDescending}

Вызов сортировки

  [array sortUsingFunction:sortTagByName context:nil];

Это многократно вызывает вашу функцию для каждого элемента в массиве, чтобы отсортировать массив.

Если вы хотите более точно определить тип сортировки, в NSString есть ряд других методов, которые могут выполнять сравнение, вот «вырезать и вставить» из NSString.h, который должен помочь вам начать, если вы хотитеисследуйте его далее.

- (NSComparisonResult)compare:(NSString *)string;
- (NSComparisonResult)compare:(NSString *)string options:(NSStringCompareOptions)mask;
- (NSComparisonResult)compare:(NSString *)string options:(NSStringCompareOptions)mask range:(NSRange)compareRange;
- (NSComparisonResult)compare:(NSString *)string options:(NSStringCompareOptions)mask range:(NSRange)compareRange locale:(id)locale; // locale arg used to be a dictionary pre-Leopard. We now accepts NSLocale. Assumes the current locale if non-nil and non-NSLocale.
- (NSComparisonResult)caseInsensitiveCompare:(NSString *)string;
- (NSComparisonResult)localizedCompare:(NSString *)string;
- (NSComparisonResult)localizedCaseInsensitiveCompare:(NSString *)string;

Отвечая на второй вопрос, вам придется делать это всякий раз, когда вы добавляете или перемещаете элемент, который может привести к несортировке массива.

hopeэто помогает.

3 голосов
/ 18 января 2012

Самый простой способ, который я знаю, это использовать sortDescriptor:

// Sort the tags by name 
NSSortDescriptor * firstDescriptor = [[[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES selector:@selector(caseInsensitiveCompare:)]

NSArray * descriptors = [NSArray arrayWithObjects:firstDescriptor, nil]; 
NSArray * sortedArray = [tagsArray sortedArrayUsingDescriptors:descriptors];
...