帮助跨两个属性对NSArray进行排序(使用NSSortDescriptor?)

Jaa*_*nus 8 sorting cocoa nsarray nssortdescriptor

我有点像NSSortDescriptor n00b.不过,我认为它是我需要做的正确工具:

我有一个由带有键的对象组成的NSArray,比如"name"和"time".这是一个例子,而不是用语言表达它:

input:

name: time
B: 4
C: 8
B: 5
C: 4
A: 3
C: 2
A: 1
A: 7
B: 6


desired output:

name: time
A: 1 <---
A: 3
A: 7
C: 2 <---
C: 4
C: 8
B: 4 <---
B: 5
B: 6
Run Code Online (Sandbox Code Playgroud)

因此,值按"时间"排序,并按"名称"分组.A首先是因为他的时间值最小,而A的所有值都是相继的.然后是C,他的所有价值都是第二小的时间价值.我已经指出了确定名称排序方式的值; 在每个名称组中,按时间排序.

如何以最有效的方式从输入到输出NSArray?(cpu-和内存方面,不一定是代码方式.)我如何为此构造NSSortDescriptors,或使用任何其他方法?我不想自己动手,除非这是最有效的方式.

小智 20

我的解决方案是:

    NSSortDescriptor *sortDescriptor1 = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES];
    NSSortDescriptor *sortDescriptor2 = [[NSSortDescriptor alloc] initWithKey:@"time" ascending:YES];
    NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor1, sortDescriptor2, nil];
Run Code Online (Sandbox Code Playgroud)

你可以尝试一下


Ben*_*hen 18

该方法可满足您的大部分需求:sortedArrayUsingDescriptors: NSArray

第一个描述符指定用于对接收者内容进行排序的主键路径.任何后续描述符用于进一步细化具有重复值的对象的排序.有关其他信息,请参阅NSSortDescriptor.

NSPredicate还需要一些过滤:

NSSortDescriptor *timeSD = [NSSortDescriptor sortDescriptorWithKey: @"time" ascending: YES];

NSMutableArray *sortedByTime = [UnsortedArray sortedArrayUsingDescriptors: timeSD];
NSMutableArray *sortedArray = [NSMutableArray arrayWithCapacity:[sortedByTime count]];

while([sortedByTime count]) 
{
        id groupLead = [sortedByTime objectAtIndex:0];  
        NSPredicate *groupPredicate = [NSPredicate predicateWithFormat:@"name = %@", [groupLead name]];

        NSArray *group = [sortedByTime filteredArrayUsingPredicate: groupPredicate];

        [sortedArray addObjectsFromArray:group];
        [sortedByTime removeObjectsInArray:group];
}
Run Code Online (Sandbox Code Playgroud)

我不知道这是否是最有效的方法,但在您有理由相信它导致问题之前,无需担心性能影响.这是不成熟的优化.我不会对这种方法的性能有任何担忧.你必须相信这个框架,否则你最终会因为毫无根据的偏执而重写它(从而破坏了框架的重点).