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

发布于 2024-07-26 01:09:08 字数 154 浏览 8 评论 0原文

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

What's the most efficient way to sort objects in an NSSet/NSMutableSet based on a property of the objects in the set? Right now the way I am doing it is by iterating through each object, add them to a NSMutableArray, and sort that array with NSSortDescriptor.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

长伴 2024-08-02 01:09:08

尝试使用

[[mySet allObjects] sortedArrayUsingDescriptors:descriptors];

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

[mySet sortedArrayUsingDescriptors:descriptors];

try using

[[mySet allObjects] sortedArrayUsingDescriptors:descriptors];

Edit: For iOS ≥ 4.0 and Mac OS X ≥ 10.6 you can directly use

[mySet sortedArrayUsingDescriptors:descriptors];
别念他 2024-08-02 01:09:08

对一组对象进行排序的“最有效方法”根据您的实际含义而有所不同。 随意的假设(前面的答案所做的)是对集合中的对象进行一次性排序。 在这种情况下,我想说这几乎是 @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 不会。 正是这个问题促使我开发类似的东西供我自己使用。

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

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

The "most efficient way" to sort a set of objects varies based on what you actually mean. The casual assumption (which the previous answers make) is a one-time sort of objects in a set. In this case, I'd say it's pretty much a toss-up between what @cobbal suggests and what you came up with — probably something like the following:

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

(I say it's a toss-up because @cobbal's approach creates two autoreleased arrays, so the memory footprint doubles. This is inconsequential for small sets of objects, but technically, neither approach is very efficient.)

However, if you're sorting the elements in the set more than once (and especially if it's a regular thing) this is definitely not an efficient approach. You could keep an NSMutableArray around and keep it synchronized with the NSSet, then call -sortUsingDescriptors: each time, but even if the array is already sorted it will still require N comparisons.

Cocoa by itself just doesn't provide an efficient approach for maintaining a collection in sorted order. Java has a TreeSet class which maintains the elements in sorted order whenever an object is inserted or removed, but Cocoa does not. It was precisely this problem that drove me to develop something similar for my own use.

As part of a data structures framework I inherited and revamped, I created a protocol and a few implementations for sorted sets. Any of the concrete subclasses will maintain a set of distinct objects in sorted order. There are still refinements to be made — the foremost being that it sorts based on the result of -compare: (which each object in the set must implement) and doesn't yet accept an NSSortDescriptor. (A workaround is to implement -compare: to compare the property of interest on the objects.)

One possible drawback is that these classes are (currently) not subclasses of NS(Mutable)Set, so if you must pass an NSSet, it won't be ordered. (The protocol does have a -set method which returns an NSSet, which is of course unordered.) I plan to rectify that soon, as I've done with the NSMutableDictionary subclasses in the framework. Feedback is definitely welcome. :-)

多情癖 2024-08-02 01:09:08

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

For iOS ≥ 5.0 and Mac OS X ≥ 10.7 you can directly use NSOrderedSet

奢华的一滴泪 2024-08-02 01:09:08

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];

NSSet is a collection of unordered objects. Looking at apple references Arrays are ordered collections.

Looking at NSArray there is a discussion with examples of sorting at
http://developer.apple.com/documentation/Cocoa/Conceptual/Collections/Articles/sortingFilteringArrays ...

Example from the link:

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];
骄兵必败 2024-08-02 01:09:08

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

NSArray *myArray = [mySet sortedArrayUsingDescriptors:descriptors];

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

You can't sort NSSet, because "sortedArrayUsingFunction:" set result as NSArray...
And all upper hint work with only Array :)

NSArray *myArray = [mySet sortedArrayUsingDescriptors:descriptors];

Work perfect, and not need other way :)

假情假意假温柔 2024-08-02 01:09:08

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

Since OS X 10.7 and iOS 5.0 there's NSOrderedSet. You can use it to keep objects in set and keep their order. NSMutableOrderedSet has methods for sorting.
In some situations this may give a performance improvement, since you don't have to create separate object like NSArray to store sorted items.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文