Getting an object from an NSSet

95,881

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]
Share:
95,881
node ninja
Author by

node ninja

Updated on July 08, 2022

Comments

  • node ninja
    node ninja almost 2 years

    If you can't get an object with objectAtIndex: from an NSSet then how do you retrieve objects?

  • Nico
    Nico over 13 years
    You can also look up a known object by a potential duplicate by sending the set a member: message. If it returns nil, 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 implement hash and isEqual: for this to be useful.
  • iosMentalist
    iosMentalist almost 12 years
    do 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
    Jason about 11 years
    just sort the resulting array with an NSSortPredicate and you'll be fine
  • fumoboy007
    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
    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 the isEqual: method), they must have the same hash value.” Currently, NSObject's implementations of hash and isEqual: use the object's identity (address). If you override isEqual:, you're setting up the possibility of objects that are not identical but are equal—which, if you don't also override hash, will still have different hashes. That violates the requirement that equal objects have equal hashes.
  • Nico
    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
    fumoboy007 over 10 years
    @PeterHosey Oops…I mistakenly thought that the default implementation of -[NSObject hash] was 0. That explains a lot. =S
  • akw
    akw over 10 years
    If you're only interested in one specific object, better use the filteredSetUsingPredicate approach.
  • John D.
    John D. over 9 years
    Should be: MyObject *object = [myArray objectAtIndex:(NSUInteger *)]