排序NSSet的最有效方法是什么?

时间:2009-07-01 00:59:58

标签: objective-c cocoa data-structures sorting nsset

根据集合中对象的属性,对NSSet / NSMutableSet中的对象进行排序的最有效方法是什么?现在,我这样做的方法是迭代每个对象,将它们添加到NSMutableArray,然后用NSSortDescriptor对该数组进行排序。

6 个答案:

答案 0 :(得分:114)

尝试使用

[[mySet allObjects] sortedArrayUsingDescriptors:descriptors];

修改:对于iOS≥4.0且Mac OSX≥10.6,您可以直接使用

[mySet sortedArrayUsingDescriptors:descriptors];

答案 1 :(得分: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却没有。正是这个问题促使我为自己开发了类似的东西。

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

一个可能的缺点是这些类(当前)不是NS(Mutable)Set的子类,因此如果必须传递NSSet,则不会对它进行排序。 (该协议确实有一个-set方法,它返回一个NSSet,当然是无序的。)我打算很快纠正这个问题,因为我已经完成了框架中的NSMutableDictionary子类。绝对欢迎反馈。 : - )

答案 2 :(得分:8)

对于iOS≥5.0和Mac OSX≥10.7,您可以直接使用NSOrderedSet

答案 3 :(得分: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];

答案 4 :(得分:0)

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

NSArray *myArray = [mySet sortedArrayUsingDescriptors:descriptors];

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

答案 5 :(得分:0)

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