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

时间:2022-10-22 10:52:07

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.

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

6 个解决方案

#1


111  

try using

试着用

[[mySet allObjects] sortedArrayUsingDescriptors:descriptors];

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

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

[mySet sortedArrayUsingDescriptors:descriptors];

#2


15  

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.)

(我说这是一个大问题,因为@cobbal的方法创建了两个自动上传的数组,所以内存占用增加了一倍。这对于小的对象集来说是无关紧要的,但是从技术上讲,这两种方法都不是非常有效的。

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.

但是,如果您对集合中的元素进行多次排序(特别是如果它是一个常规的东西),那么这肯定不是一种有效的方法。您可以保留一个NSMutableArray并使它与NSSet保持同步,然后调用-sortUsingDescriptors:每次,但是即使数组已经排序,它仍然需要N个比较。

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.

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

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.)

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

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. :-)

一个可能的缺点是这些类(当前)不是NS(可变)集合的子类,所以如果您必须传递一个NSSet,它就不会被排序。(该协议有一个-set方法,它返回一个NSSet,当然这是无序的。)我打算尽快纠正这个问题,因为我已经在框架中使用了NSMutableDictionary子类。反馈无疑是受欢迎的。:-)

#3


8  

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

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

#4


2  

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

NSSet是一个无序对象的集合。查看apple references数组是有序集合。

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

看看NSArray,有一个关于排序的例子: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];

#5


0  

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

不能对NSSet排序,因为“sortedArrayUsingFunction:”将结果设置为NSArray…所有上面的提示都只对数组有效)

NSArray *myArray = [mySet sortedArrayUsingDescriptors:descriptors];

Work perfect, and not need other way :)

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

#6


0  

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.

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

#1


111  

try using

试着用

[[mySet allObjects] sortedArrayUsingDescriptors:descriptors];

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

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

[mySet sortedArrayUsingDescriptors:descriptors];

#2


15  

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.)

(我说这是一个大问题,因为@cobbal的方法创建了两个自动上传的数组,所以内存占用增加了一倍。这对于小的对象集来说是无关紧要的,但是从技术上讲,这两种方法都不是非常有效的。

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.

但是,如果您对集合中的元素进行多次排序(特别是如果它是一个常规的东西),那么这肯定不是一种有效的方法。您可以保留一个NSMutableArray并使它与NSSet保持同步,然后调用-sortUsingDescriptors:每次,但是即使数组已经排序,它仍然需要N个比较。

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.

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

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.)

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

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. :-)

一个可能的缺点是这些类(当前)不是NS(可变)集合的子类,所以如果您必须传递一个NSSet,它就不会被排序。(该协议有一个-set方法,它返回一个NSSet,当然这是无序的。)我打算尽快纠正这个问题,因为我已经在框架中使用了NSMutableDictionary子类。反馈无疑是受欢迎的。:-)

#3


8  

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

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

#4


2  

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

NSSet是一个无序对象的集合。查看apple references数组是有序集合。

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

看看NSArray,有一个关于排序的例子: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];

#5


0  

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

不能对NSSet排序,因为“sortedArrayUsingFunction:”将结果设置为NSArray…所有上面的提示都只对数组有效)

NSArray *myArray = [mySet sortedArrayUsingDescriptors:descriptors];

Work perfect, and not need other way :)

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

#6


0  

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.

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