I have used NSSets many times in my apps, but I have never created one myself.
When is it better to use an NSSet
as opposed to an NSArray
and why?
I have used NSSets many times in my apps, but I have never created one myself.
When is it better to use an NSSet
as opposed to an NSArray
and why?
When the order of the items in the collection is not important, sets offer better performance for finding items in the collection.
The reason is that a set uses hash values to find items (like a dictionary) while an array has to iterate over its entire contents to find a particular object.
The image from Apple's Documentation describes it very well:
Array
is an ordered (order is maintained when you add) sequence of elements
[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
is a distinct (no duplicates), unordered list of elements
[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]
The best answer is to this is Apple's own documentation.
The main difference is that NSArray
is for an ordered collection and NSSet
is for an unordered collection.
There are several articles out there that talk about the difference in speed between the two, like this one. If you're iterating through an unordered collection, NSSet
is great. However, in many cases, you need to do things that only an NSArray
can do, so you sacrifice the speed for those abilities.
NSSet
NSArray
That's all there really is to it! Let me know if that helps.
NSOrderedSet is available in iOS 5+ so with that the main difference becomes whether you want duplicate objects in the data structure.
NSArray:
NSSet:
An array is used to access items by their index. Any item can be inserted into the array multiple times. Arrays mantain the order of their elements.
A set is used basically only to check if the item is in the collection or not. The items have no concept of order or indexing. You cannot have an item in a set twice.
If an array wants to check if it contains an element, it has to check all its items. Sets are designed to use faster algorithms.
You can imagine a set like a dictionary without values.
Note that array and set are not the only data structures. There are other, e.g. Queue, Stack, Heap, Fibonacci's Heap. I would recommend reading a book about algorithms and data structures.
See wikipedia for more information.
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);
the array
2015-12-04 11:05:40.935 [598:15730] ( 1, 2, 3, 4, 2, 1 )
the set
2015-12-04 11:05:43.362 [598:15730] { ( 3, 1, 2, 5 )}
The main differences have already been given in other answers.
I'd just like to note that because of the way sets and dictionaries are implemented (i.e. using hashes),one should be careful not to use mutable objects for the keys.
If a key is mutated then the hash will (probably) change too, pointing to a different index/bucket in the hash table. The original value won't be deleted and will actually be taken into account when enumerating or asking the structure for its size/count.
This can lead to some really hard to locate bugs.
Here you can find a pretty thorough comparison of the NSArray
and NSSet
datastructures.
Short conclusions:
Yes, NSArray is faster than NSSet for simply holding and iterating. As little as 50% faster for constructing and as much as 500% faster for iterating. Lesson: if you only need to iterate contents, don't use an NSSet.
Of course, if you need to test for inclusion, work hard to avoid NSArray. Even if you need both iteration and inclusion testing, you should probably still choose an NSSet. If you need to keep your collection ordered and also test for inclusion, then you should consider keeping two collections (an NSArray and an NSSet), each containing the same objects.
NSDictionary is slower to construct than NSMapTable — since it needs to copy the key data. It makes up for this by being faster to lookup. Of course, the two have different capabilities so most of the time, this determination should be made on other factors.
You would typically use a Set when access speed is of the essence and order doesn’t matter, or is determined by other means (through a predicate or sort descriptor). Core Data for example uses sets when managed objects are accessed via a to-many relationship
Just to add a bit of it i use set sometimes just to remove duplicates from array like :-
NSMutableSet *set=[[NSMutableSet alloc]initWithArray:duplicateValueArray]; // will remove all the duplicate values