什么时候在NSArray上使用NSSet更好?

时间:2012-06-12 13:11:04

标签: ios objective-c arrays cocoa cocoa-touch

我在我的应用程序中多次使用NSSets,但我自己从未创建过。

什么时候使用NSSet而不是NSArray更好?为什么?

11 个答案:

答案 0 :(得分:176)

来自Apple's Documentation的图片描述得非常好:

Objective-C Collections

Array有序(添加时维护订单)元素序列

[array addObject:@1];
[array addObject:@2];
[array addObject:@3];
[array addObject:@4];
[array addObject:@6];
[array addObject:@4];
[array addObject:@1];
[array addObject:@2];

[1, 2, 3, 4, 6, 4, 1, 2]

Set不同(无重复),无序元素列表

[set addObject:@1];
[set addObject:@2];
[set addObject:@3];
[set addObject:@4];
[set addObject:@6];
[set addObject:@4];
[set addObject:@1];
[set addObject:@2];

[1, 2, 6, 4, 3]

答案 1 :(得分:166)

当集合中的项目顺序不重要时,集合可以更好地查找集合中的项目。

原因是一个集合使用哈希值来查找项目(比如字典),而数组必须迭代其整个内容才能找到特定的对象。

答案 2 :(得分:65)

最好的答案是Apple's own documentation

enter image description here

主要区别在于NSArray用于有序集合,NSSet用于无序集合。

有几篇文章讨论了两者之间的速度差异,例如this one。如果您正在迭代无序集合,NSSet很棒。但是,在许多情况下,你需要做只有NSArray可以做的事情,所以你牺牲了这些能力的速度。

<强>的NSSet

  • 主要通过比较访问项目
  • 无序
  • 不允许重复

<强>的NSArray

  • 可以按索引访问项目
  • 允许重复

这就是真的!如果有帮助,请告诉我。

答案 3 :(得分:12)

NSOrderedSet在iOS 5+中可用,因此主要区别在于您是否需要数据结构中的重复对象。

答案 4 :(得分:9)

<强>的NSArray

  1. 有序的数据收集
  2. 允许重复
  3. 是集合类型对象
  4. <强>的NSSet

    1. 无序的数据收集
    2. 不允许重复
    3. 它也是集合类型对象

答案 5 :(得分:7)

数组用于按索引访问项目。任何项目都可以多次插入到数组中。数组保持元素的顺序。

基本上只用于检查项目是否在集合中。这些项目没有订单或索引的概念。你不能在一组中有一个项目。

如果数组想要检查它是否包含元素,则必须检查其所有项目。集合旨在使用更快的算法。

您可以想象一个没有值的字典集。

请注意,数组和集不是唯一的数据结构。还有其他,例如队列,堆栈,堆,斐波那契的堆。我建议你读一本关于算法和数据结构的书。

有关详细信息,请参阅wikipedia

答案 6 :(得分:5)

NSArray *Arr;
NSSet *Nset;

Arr=[NSArray arrayWithObjects:@"1",@"2",@"3",@"4",@"2",@"1", nil];
Nset=[NSSet setWithObjects:@"1",@"2",@"3",@"3",@"5",@"5", nil];

NSLog(@"%@",Arr);
NSLog(@"%@",Nset);

数组

  

2015-12-04 11:05:40.935 [598:15730](1,2,3,4,2,1)

集合

  

2015-12-04 11:05:43.362 [598:15730] {(3,1,2,5)}

答案 7 :(得分:4)

其他答案已经给出了主要的区别。

我只想指出,由于实现集合和字典的方式(即使用哈希),应该注意不要使用可变对象作为键。

如果一个键被改变,那么哈希将(可能)也会改变,指向哈希表中的不同索引/桶。原始值不会被删除,在枚举或询问结构的大小/数量时实际会被考虑在内。

这可能导致一些人很难找到错误。

答案 8 :(得分:3)

Here您可以找到NSArrayNSSet数据结构的完整比较。

简短的结论:

  

是的,NSArray比NSSet更快,只需保持和迭代。构建速度提高50%,迭代速度提高500%。课程:如果您只需要迭代内容,请不要使用NSSet。

     

当然,如果您需要测试是否包含在内,请努力避免使用NSArray。即使您需要迭代和包含测试,您仍应该选择NSSet。如果你需要保持你的收集顺序并测试包含,那么你应该考虑保留两个集合(一个NSArray和一个NSSet),每个集合包含相同的对象。

     

NSDictionary的构造速度比NSMapTable慢 - 因为它需要复制关键数据。它通过更快地查找来弥补这一点。当然,两者在大多数情况下具有不同的能力,这个决定应该在其他因素上做出。

答案 9 :(得分:2)

当访问速度至关重要并且顺序无关紧要时,您通常会使用设置,或者通过其他方式(通过谓词或排序描述符)确定。例如,核心数据在通过多对多关系访问托管对象时使用集合

答案 10 :(得分:1)

只是为了添加一点,我使用set有时只是为了从数组中删除重复项,如: -

NSMutableSet *set=[[NSMutableSet alloc]initWithArray:duplicateValueArray]; // will remove all the duplicate values