NSArray 排序和隔离

Posted

技术标签:

【中文标题】NSArray 排序和隔离【英文标题】:NSArray sort and isolate 【发布时间】:2010-01-24 14:10:45 【问题描述】:

我有一个 NSArray 名称,我想将它们按字母顺序排序到 UITableView 中并将它们分成几个部分。

我在顶部有一个标记部分,即第 0 部分。我希望按字母顺序排列的名称排在后面。因此,所有以 A 开头的名称都放入第 1 部分,B 放入第 2 部分,依此类推。

我需要能够以某种方式获取每个部分的行数,然后将对象放在每个部分中。

我该怎么做?

【问题讨论】:

【参考方案1】:

下面是 NSArray 上的类别进行分组的方法:

@interface NSArray (Grouping)
- (NSArray*) groupUsingFunction: (id (*)(id, void*)) function context: (void*) context;
@end

@implementation NSArray (Grouping)
- (NSArray*) groupUsingFunction: (id (*)(id, void*)) function context: (void*) context

    NSArray* groupedArray = nil;

    NSMutableDictionary* dictionary = [NSMutableDictionary new];
    if (dictionary != nil)
    
        for (id item in self)
        
            id key = function(item, context);
            if (key != nil)
            
                NSMutableArray* array = [dictionary objectForKey: key];
                if (array == nil) 
                    array = [NSMutableArray arrayWithObject: item];
                    if (array != nil) 
                        [dictionary setObject: array forKey: key];
                    
                 else 
                    [array addObject: item];
                
            
        

        groupedArray = [NSMutableArray arrayWithArray: [dictionary allValues]];
        [dictionary release];
    

    return groupedArray;

@end

你可以这样使用它:

id GroupNameByFirstLetter(NSString* object, void* context)

    return [object substringToIndex: 1];


NSInteger SortGroupedNamesByFirstLetter(id left, id right, void* context)

    return [[left objectAtIndex: 0] characterAtIndex: 0] - [[right objectAtIndex: 0] characterAtIndex: 0];


NSMutableArray* names = [NSArray arrayWithObjects: @"Stefan", @"John", @"Alex",
    @"Sue", @"Aura", @"Mikki", @"Michael", @"Joe", @"Steve", @"Mac", @"Fred",
    @"Faye", @"Paul", nil];

// Group the names and then sort the groups and the contents of the groups.

groupedNames_ = [[names groupUsingFunction: GroupNameByFirstLetter context: nil] retain];

[groupedNames_ sortUsingFunction: SortGroupedNamesByFirstLetter context: nil];

for (NSUInteger i = 0; i < [groupedNames_ count]; i++) 
    [[groupedNames_ objectAtIndex: i] sortUsingSelector: @selector(compare:)];

【讨论】:

【参考方案2】:

我将 St3fans 的答案修改为更现代一点,并改为使用 Blocks:

@interface NSArray (Grouping)
- (NSArray*) groupUsingBlock:(NSString* (^)(id object)) block;
@end


- (NSArray*) groupUsingBlock:(NSString* (^)(id object)) block

    NSArray* groupedArray = nil;

    NSMutableDictionary* dictionary = [NSMutableDictionary new];
    if (dictionary != nil)
    
        for (id item in self)
        
            id key = block(item);
            if (key != nil)
            
                NSMutableArray* array = [dictionary objectForKey: key];
                if (array == nil) 
                    array = [NSMutableArray arrayWithObject: item];
                    if (array != nil) 
                        [dictionary setObject: array forKey: key];
                    
                 else 
                    [array addObject: item];
                
            
        

        groupedArray = [NSMutableArray arrayWithArray: [dictionary allValues]];
        [dictionary release];
    

    return groupedArray;

你可以这样使用它:

NSArray *grouped = [arrayToGroup groupUsingBlock:^NSString *(id object) 
        return [object valueForKey:@"name"];
];

【讨论】:

【参考方案3】:

您可能应该创建一个数组数组,每个字母一个,并以这种方式存储您的姓名。虽然您可以使用单个数组进行存储,但没有快速的方法来进行您正在寻找的分段。排序,当然,但不是分段。

【讨论】:

以上是关于NSArray 排序和隔离的主要内容,如果未能解决你的问题,请参考以下文章

NSArray排序

根据对另一个 NSArray 字符串的排序,对自定义对象的 NSArray 进行排序

如何按数组计数对嵌套 NSArray 的 NSArray 进行排序?

按二维排序 NSArray - Objective-C

NSSortDescriptor 不排序 NSArray

按降序排序数组(NSArray)