数组排序

数组排序

引用来源:http://objccn.io/issue-7-1/

如果数组存储的是字符串对象,sortedArrayUsingSelector:是第一选择:

NSArray *array = @[@"John Appleseed", @"Tim Cook", @"Hair Force One", @"Michael Jurewitz"];
NSArray *sortedArray = [array sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)];

下面的代码对存储数字的内容同样很好,因为 NSNumber 实现了 compare::

NSArray *numbers = @[@9, @5, @11, @3, @1];
NSArray *sortedNumbers = [numbers sortedArrayUsingSelector:@selector(compare:)];

如果想更可控,可以使用基于函数指针的排序方法:

- (NSData *)sortedArrayHint;
- (NSArray *)sortedArrayUsingFunction:(NSInteger (*)(id, id, void *))comparator
                      context:(void *)context;
- (NSArray *)sortedArrayUsingFunction:(NSInteger (*)(id, id, void *))comparator
                      context:(void *)context hint:(NSData *)hint;

苹果增加了一个方法来加速使用 sortedArrayHint 的排序。

hinted sort 方式在你有一个已排序的大数组 (N 个元素) 并且只改变其中一小部分(P 个添加和删除,这里 P远小于 N)时,会非常有效。你可以重用原来的排序结果,然后在 N 个老项目和 P 个新项目进行一个概念上的归并排序。为了得到合适的 hint,你应该在原来的数组排序后使用 sortedArrayHint 来在你需要的时候(比如在数组改变后想重新排序时)保证持有它。

因为block的引入,也出现了一些基于block的排序方法:

- (NSArray *)sortedArrayUsingComparator:(NSComparator)cmptr;
- (NSArray *)sortedArrayWithOptions:(NSSortOptions)opts
            usingComparator:(NSComparator)cmptr;

性能上来说,不同的方法间并没有太多的不同。有趣的是,基于 selector 的方式是最快的。可以在 GitHub 上找到测试用的源代码:

Sorting 1000000 elements. selector: 4947.90[ms] function: 5618.93[ms] block: 5082.98[ms].