68

根据集合中对象的属性对NSSet/中的对象进行排序的最有效方法是什么?NSMutableSet现在我这样做的方式是遍历每个对象,将它们添加到 aNSMutableArray中,然后使用NSSortDescriptor.

4

6 回答 6

117

尝试使用

[[mySet allObjects] sortedArrayUsingDescriptors:descriptors];

编辑:对于 iOS ≥ 4.0 和 Mac OS X ≥ 10.6,您可以直接使用

[mySet sortedArrayUsingDescriptors:descriptors];
于 2009-07-01T01:12:21.527 回答
15

对一组对象进行排序的“最有效方式”取决于您的实际意思。随意的假设(前面的答案所做的)是一组中的一次性对象。在这种情况下,我想说这几乎是@cobbal建议和你想出的东西之间的折腾——可能类似于以下内容:

NSMutableArray* array = [NSMutableArray arrayWithCapacity:[set count]];
for (id anObject in set)
    [array addObject:anObject];
[array sortUsingDescriptors:descriptors];

(我说这是一个折腾,因为@cobbal 的方法创建了两个自动释放的数组,所以内存占用加倍。这对于小对象集无关紧要,但从技术上讲,这两种方法都不是很有效。)

但是,如果您不止一次地对集合中的元素进行排序(尤其是在常规情况下),这绝对不是一种有效的方法。您可以保留一个 NSMutableArray 并使其与 NSSet 保持同步,然后每次调用 -sortUsingDescriptors:,但即使数组已经排序,它仍然需要 N 次比较。

Cocoa 本身并没有提供一种有效的方法来维护一个有序的集合。Java 有一个TreeSet类,它在插入或删除对象时按排序顺序维护元素,但 Cocoa 没有。正是这个问题促使我开发了类似的东西供我自己使用。

作为我继承和改进的数据结构框架的一部分,我为 sorted sets 创建了一个协议和一些实现。任何具体的子类都将按排序顺序维护一组不同的对象。仍然需要改进——最重要的是它基于 -compare: 的结果进行排序(集合中的每个对象都必须实现)并且还不接受 NSSortDescriptor。(一种解决方法是实现 -compare:比较对象上感兴趣的属性。)

一个可能的缺点是这些类(当前)不是 NS(Mutable)Set 的子类,所以如果你必须传递一个 NSSet,它就不会被排序。(该协议确实有一个返回 NSSet 的 -set 方法,它当然是无序的。)我计划尽快纠正这个问题,就像我对框架中的 NSMutableDictionary 子类所做的那样。绝对欢迎反馈。:-)

于 2009-07-01T04:20:53.373 回答
8

对于 iOS ≥ 5.0 和 Mac OS X ≥ 10.7 可以直接使用NSOrderedSet

于 2012-01-12T18:39:15.043 回答
2

NSSet 是无序对象的集合。查看苹果引用数组是有序集合。

查看 NSArray,在 http://developer.apple.com/documentation/Cocoa/Conceptual/Collections/Articles/sortingFilteringArrays 上有一个关于排序示例的讨论...

链接中的示例:

NSInteger alphabeticSort(id string1, id string2, void *reverse)
{
    if (*(BOOL *)reverse == YES) {
        return [string2 localizedCaseInsensitiveCompare:string1];
    }
    return [string1 localizedCaseInsensitiveCompare:string2];
}

// assuming anArray is array of unsorted strings

NSArray *sortedArray;

// sort using a selector
sortedArray =
    [anArray sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)];

// sort using a function
BOOL reverseSort = NO;
sortedArray =
    [anArray sortedArrayUsingFunction:alphabeticSort context:&reverseSort];
于 2009-07-01T01:09:13.483 回答
0

您无法对 NSSet 进行排序,因为“sortedArrayUsingFunction:”将结果设置为 NSArray ...并且所有上层提示仅适用于 Array :)

NSArray *myArray = [mySet sortedArrayUsingDescriptors:descriptors];

工作完美,不需要其他方式:)

于 2011-04-25T04:30:51.553 回答
0

从 OS X 10.7 和 iOS 5.0 开始,有NSOrderedSet. 您可以使用它来保持对象的集合并保持它们的顺序。NSMutableOrderedSet有排序的方法。在某些情况下,这可能会提高性能,因为您不必创建单独的对象NSArray来存储已排序的项目。

于 2016-06-01T05:45:36.600 回答