Getting an object from an NSSet
Solution 1
There are several use cases for a set. You could enumerate through (e.g. with enumerateObjectsUsingBlock
or NSFastEnumeration), call containsObject
to test for membership, use anyObject
to get a member (not random), or convert it to an array (in no particular order) with allObjects
.
A set is appropriate when you don't want duplicates, don't care about order, and want fast membership testing.
Solution 2
NSSet doesn't have a method objectAtIndex:
Try calling allObjects which returns an NSArray of all the objects.
Solution 3
it is possible to use filteredSetUsingPredicate if you have some kind of unique identifier to select the object you need.
First create the predicate (assuming your unique id in the object is called "identifier" and it is an NSString):
NSPredicate *myPredicate = [NSPredicate predicateWithFormat:@"identifier == %@", identifier];
And then choose the object using the predicate:
NSObject *myChosenObject = [mySet filteredSetUsingPredicate:myPredicate].anyObject;
Solution 4
NSArray *myArray = [myNSSet allObjects];
MyObject *object = [myArray objectAtIndex:(NSUInteger *)]
replace NSUInteger with the index of your desired object.
Solution 5
For Swift3 & iOS10 :
//your current set
let mySet : NSSet
//targetted index
let index : Int
//get object in set at index
let object = mySet.allObjects[index]
node ninja
Updated on July 08, 2022Comments
-
node ninja almost 2 years
If you can't get an object with objectAtIndex: from an NSSet then how do you retrieve objects?
-
Nico over 13 yearsYou can also look up a known object by a potential duplicate by sending the set a
member:
message. If it returnsnil
, the set does not contain an object equal to the one you passed; if it returns an object pointer, then the pointer it returns is to the object already in the set. The objects in the set must implementhash
andisEqual:
for this to be useful. -
iosMentalist almost 12 yearsdo you have any idea if the array returned is ordered? in other words, if im adding objects to the set using "setByAddingObject", and i used "allObjects", are? the elements in the array ordered in the order I added the objects?
-
Jason about 11 yearsjust sort the resulting array with an NSSortPredicate and you'll be fine
-
fumoboy007 over 10 years@PeterHosey I don't think
hash
needs to be implemented; it would just go a lot faster if you did do that. -
Nico over 10 years@fumoboy007: For storage in a set or use as a key in a dictionary, yes it does. From the documentation of
hash
in the NSObject protocol: “If two objects are equal (as determined by theisEqual:
method), they must have the same hash value.” Currently, NSObject's implementations ofhash
andisEqual:
use the object's identity (address). If you overrideisEqual:
, you're setting up the possibility of objects that are not identical but are equal—which, if you don't also overridehash
, will still have different hashes. That violates the requirement that equal objects have equal hashes. -
Nico over 10 years@fumoboy007: Consider how a hash table works: The container has an array of some number of buckets, and uses each incoming object's hash to determine which bucket that object should be in. For lookups such as
member:
, the container will only look in that one bucket (which is why sets are so much faster than arrays at membership testing and dictionaries are so much faster than parallel arrays at key-value lookup). If the object being sought has the wrong hash, then the container will look in the wrong bucket, and not find a match. -
fumoboy007 over 10 years@PeterHosey Oops…I mistakenly thought that the default implementation of
-[NSObject hash]
was 0. That explains a lot. =S -
akw over 10 yearsIf you're only interested in one specific object, better use the filteredSetUsingPredicate approach.
-
John D. over 9 yearsShould be: MyObject *object = [myArray objectAtIndex:(NSUInteger *)]