I can grab a random value from an array-like structure by retrieving a random index.
How can I grab a random value from an NSSet object that stores NSNumber objects? I couldn't find an instance method of NSSet that retrieves a random value.
In short, you can't directly retrieve a random object from an NSSet
.
You either need to turn the set into an array -- into something that has an index that can be randomized -- by re-architecting your code to use an array or you could implement this using this bit of pseudo-code:
randomIndex = ...random-generator....(0 .. [set count]);
__block currentIndex = 0;
__block selectedObj = nil;
[set enumerateObjectsWithOptions:^(id obj, BOOL *stop) {
if (randomIndex == currentIndex) { selectedObj = obj; *stop = YES }
else currentIndex++;
}];
return selectedObj;
Yes -- it iterates the set, potentially the whole set, when grabbing the object. However, that iteration is pretty much what'll happen in the conversion to an NSArray anyway. As long as the set isn't that big and you aren't calling it that often, no big deal.
Whilst I like that @bbum answer will terminate early on some occasions due to the use of stop
in the enumeration block.
For readability and ease of remembering what is going on when you revisit this code in the future I would go with his first suggestion of turn the set into an array
NSInteger randomIndex = ..random-generator....(0 .. [set count])
id obj = [set count] > 0 ? [[set allObjects] objectAtIndex:randomIndex] : nil;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With