-[NSMutableSet randomObject]
I'd like to extend Apple implementation of NSMutableSet to include a randomObject method. The purpose of this method is self-explanatory and its potential use is I'm sure obvious to most of you. For my first idea I thought about simply adding a category to NSMutableSet but any obvious implementation of -randomObject would require accessing existing instance variables or adding my own in order to implement the random access I would need to for the set. I also don't know how objects are stored internally. Is it an array? Is it a key/value pair? I don't know. How am I going to correlate the random numbers I generate with the objects in the set? Next, I thought about using inheritance with NSMutableArray. I even wrote some code: + (void)initialize { if ( self == [MCRandomlyAccessedArray class] ) { srandom(time(NULL)); } } - (id)randomObject { // If the array is empty, throw an exception. The caller should know better. // If there is only one, return object zero every time. // If there are only two, alternate with every access. // If there are three or more, randomize but never provide the same object // twice in a row. if ( [self count] ) { NSUInteger index = 0; if ( [self count] 1 ) { if ( 2 == [self count] ) { index = (++lastObjectIndex % 2); } else { do { index = (random() % [self count]); } while (index == lastObjectIndex); } lastObjectIndex = index; } return [self objectAtIndex:index]; } else { [[NSException exceptionWithName:NSRangeException reason:@Array is empty userInfo:nil] raise]; } return nil; // unreachable } Come to find out at runtime that this won't work either because NSMutableArray is abstract! *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSMutableArray addObject:]: method only defined for abstract class. Define -[MCRandomlyAccessedArray addObject:]!' This would seem to indicate that I need to write a lot more code in order to have a complete implementation. I'm not in the mood to re-invent the wheel. I'm not lazy, I just have a lot of other code that needs to be written, which pertains to the big picture. Next, I thought maybe I could simply wrap-up an NSMutableArray in my own class and let it do most of the heavy lifting when it comes to all of those existing methods. The only problem is that I'm no expert on how to duplicate all of the class and instance init methods and memory management code. So, that brings me to you lovely people. What do you recommend? Do I bite the bullet and re-implement NSMutableArray? If so, where can I find guidance on this? I love the containers provided by Apple. They simply work and I don't have to think about them. So much so, that I don't really know how they work. My expertise is/was in C/C++ and STL. Is there fourth alternative or something I missed in my brief examination as described above? Thanks. -Michael ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: -[NSMutableSet randomObject]
What about something like: @implementation NSSet (Random) - (id) randomObject { NSArray * allObjects = [self allObjects]; if ([allObjects count] == 0) { @throw ...; } return [allObjects objectAtIndex:(arc4random() % [allObjects count])]; } @end On May 25, 2010, at 10:49 AM, Michael A. Crawford wrote: I'd like to extend Apple implementation of NSMutableSet to include a randomObject method. The purpose of this method is self-explanatory and its potential use is I'm sure obvious to most of you. For my first idea I thought about simply adding a category to NSMutableSet but any obvious implementation of -randomObject would require accessing existing instance variables or adding my own in order to implement the random access I would need to for the set. I also don't know how objects are stored internally. Is it an array? Is it a key/value pair? I don't know. How am I going to correlate the random numbers I generate with the objects in the set? Next, I thought about using inheritance with NSMutableArray. I even wrote some code: + (void)initialize { if ( self == [MCRandomlyAccessedArray class] ) { srandom(time(NULL)); } } - (id)randomObject { // If the array is empty, throw an exception. The caller should know better. // If there is only one, return object zero every time. // If there are only two, alternate with every access. // If there are three or more, randomize but never provide the same object // twice in a row. if ( [self count] ) { NSUInteger index = 0; if ( [self count] 1 ) { if ( 2 == [self count] ) { index = (++lastObjectIndex % 2); } else { do { index = (random() % [self count]); } while (index == lastObjectIndex); } lastObjectIndex = index; } return [self objectAtIndex:index]; } else { [[NSException exceptionWithName:NSRangeException reason:@Array is empty userInfo:nil] raise]; } return nil; // unreachable } Come to find out at runtime that this won't work either because NSMutableArray is abstract! *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSMutableArray addObject:]: method only defined for abstract class. Define -[MCRandomlyAccessedArray addObject:]!' This would seem to indicate that I need to write a lot more code in order to have a complete implementation. I'm not in the mood to re-invent the wheel. I'm not lazy, I just have a lot of other code that needs to be written, which pertains to the big picture. Next, I thought maybe I could simply wrap-up an NSMutableArray in my own class and let it do most of the heavy lifting when it comes to all of those existing methods. The only problem is that I'm no expert on how to duplicate all of the class and instance init methods and memory management code. So, that brings me to you lovely people. What do you recommend? Do I bite the bullet and re-implement NSMutableArray? If so, where can I find guidance on this? I love the containers provided by Apple. They simply work and I don't have to think about them. So much so, that I don't really know how they work. My expertise is/was in C/C++ and STL. Is there fourth alternative or something I missed in my brief examination as described above? Thanks. -Michael ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/davedelong%40me.com This email sent to davedel...@me.com smime.p7s Description: S/MIME cryptographic signature ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: -[NSMutableSet randomObject]
Ah, I see; you don't want to provide the same object twice in a row. If that's the case, is it really random? ;) Dave On May 25, 2010, at 10:52 AM, Dave DeLong wrote: What about something like: @implementation NSSet (Random) - (id) randomObject { NSArray * allObjects = [self allObjects]; if ([allObjects count] == 0) { @throw ...; } return [allObjects objectAtIndex:(arc4random() % [allObjects count])]; } @end smime.p7s Description: S/MIME cryptographic signature ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: -[NSMutableSet randomObject]
Hey, not bad. Does the -allObjects method always return the same sequence? Did you just cobble this up or is this running in a system somewhere? It doesn't do everything I want but it is definitely the better part of the 80/20 rule. -Michael On May 25, 2010, at 12:52 PM, Dave DeLong wrote: What about something like: @implementation NSSet (Random) - (id) randomObject { NSArray * allObjects = [self allObjects]; if ([allObjects count] == 0) { @throw ...; } return [allObjects objectAtIndex:(arc4random() % [allObjects count])]; } @end On May 25, 2010, at 10:49 AM, Michael A. Crawford wrote: I'd like to extend Apple implementation of NSMutableSet to include a randomObject method. The purpose of this method is self-explanatory and its potential use is I'm sure obvious to most of you. For my first idea I thought about simply adding a category to NSMutableSet but any obvious implementation of -randomObject would require accessing existing instance variables or adding my own in order to implement the random access I would need to for the set. I also don't know how objects are stored internally. Is it an array? Is it a key/value pair? I don't know. How am I going to correlate the random numbers I generate with the objects in the set? Next, I thought about using inheritance with NSMutableArray. I even wrote some code: + (void)initialize { if ( self == [MCRandomlyAccessedArray class] ) { srandom(time(NULL)); } } - (id)randomObject { // If the array is empty, throw an exception. The caller should know better. // If there is only one, return object zero every time. // If there are only two, alternate with every access. // If there are three or more, randomize but never provide the same object // twice in a row. if ( [self count] ) { NSUInteger index = 0; if ( [self count] 1 ) { if ( 2 == [self count] ) { index = (++lastObjectIndex % 2); } else { do { index = (random() % [self count]); } while (index == lastObjectIndex); } lastObjectIndex = index; } return [self objectAtIndex:index]; } else { [[NSException exceptionWithName:NSRangeException reason:@Array is empty userInfo:nil] raise]; } return nil; // unreachable } Come to find out at runtime that this won't work either because NSMutableArray is abstract! *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSMutableArray addObject:]: method only defined for abstract class. Define -[MCRandomlyAccessedArray addObject:]!' This would seem to indicate that I need to write a lot more code in order to have a complete implementation. I'm not in the mood to re-invent the wheel. I'm not lazy, I just have a lot of other code that needs to be written, which pertains to the big picture. Next, I thought maybe I could simply wrap-up an NSMutableArray in my own class and let it do most of the heavy lifting when it comes to all of those existing methods. The only problem is that I'm no expert on how to duplicate all of the class and instance init methods and memory management code. So, that brings me to you lovely people. What do you recommend? Do I bite the bullet and re-implement NSMutableArray? If so, where can I find guidance on this? I love the containers provided by Apple. They simply work and I don't have to think about them. So much so, that I don't really know how they work. My expertise is/was in C/C++ and STL. Is there fourth alternative or something I missed in my brief examination as described above? Thanks. -Michael ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/davedelong%40me.com This email sent to davedel...@me.com ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/michaelacrawford%40me.com This email sent to michaelacrawf...@me.com ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription:
Re: -[NSMutableSet randomObject]
Implementation should probably include various options for what kind of pseudo randomness is desired. On May 25, 2010, at 11:52 AM, Dave DeLong wrote: What about something like: @implementation NSSet (Random) - (id) randomObject { NSArray * allObjects = [self allObjects]; if ([allObjects count] == 0) { @throw ...; } return [allObjects objectAtIndex:(arc4random() % [allObjects count])]; } @end On May 25, 2010, at 10:49 AM, Michael A. Crawford wrote: I'd like to extend Apple implementation of NSMutableSet to include a randomObject method. The purpose of this method is self-explanatory and its potential use is I'm sure obvious to most of you. For my first idea I thought about simply adding a category to NSMutableSet but any obvious implementation of -randomObject would require accessing existing instance variables or adding my own in order to implement the random access I would need to for the set. I also don't know how objects are stored internally. Is it an array? Is it a key/value pair? I don't know. How am I going to correlate the random numbers I generate with the objects in the set? Next, I thought about using inheritance with NSMutableArray. I even wrote some code: + (void)initialize { if ( self == [MCRandomlyAccessedArray class] ) { srandom(time(NULL)); } } - (id)randomObject { // If the array is empty, throw an exception. The caller should know better. // If there is only one, return object zero every time. // If there are only two, alternate with every access. // If there are three or more, randomize but never provide the same object // twice in a row. if ( [self count] ) { NSUInteger index = 0; if ( [self count] 1 ) { if ( 2 == [self count] ) { index = (++lastObjectIndex % 2); } else { do { index = (random() % [self count]); } while (index == lastObjectIndex); } lastObjectIndex = index; } return [self objectAtIndex:index]; } else { [[NSException exceptionWithName:NSRangeException reason:@Array is empty userInfo:nil] raise]; } return nil; // unreachable } Come to find out at runtime that this won't work either because NSMutableArray is abstract! *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSMutableArray addObject:]: method only defined for abstract class. Define -[MCRandomlyAccessedArray addObject:]!' This would seem to indicate that I need to write a lot more code in order to have a complete implementation. I'm not in the mood to re-invent the wheel. I'm not lazy, I just have a lot of other code that needs to be written, which pertains to the big picture. Next, I thought maybe I could simply wrap-up an NSMutableArray in my own class and let it do most of the heavy lifting when it comes to all of those existing methods. The only problem is that I'm no expert on how to duplicate all of the class and instance init methods and memory management code. So, that brings me to you lovely people. What do you recommend? Do I bite the bullet and re-implement NSMutableArray? If so, where can I find guidance on this? I love the containers provided by Apple. They simply work and I don't have to think about them. So much so, that I don't really know how they work. My expertise is/was in C/C++ and STL. Is there fourth alternative or something I missed in my brief examination as described above? Thanks. -Michael ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/davedelong%40me.com This email sent to davedel...@me.com ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/jjoyce%40apple.com This email sent to jjo...@apple.com ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: -[NSMutableSet randomObject]
Since an NSSet is, by definition, unordered, the allObjects method is not guaranteed to return the same ordering of objects every time. However, once you have the array, you could easily order it yourself using sortedArrayUsing(Selector/Comparator/Descriptors):. And I've used this code (or really similar code) in production stuff before. Dave On May 25, 2010, at 10:58 AM, Michael A. Crawford wrote: Hey, not bad. Does the -allObjects method always return the same sequence? Did you just cobble this up or is this running in a system somewhere? It doesn't do everything I want but it is definitely the better part of the 80/20 rule. -Michael smime.p7s Description: S/MIME cryptographic signature ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: -[NSMutableSet randomObject]
If this is indeed the desired effect, you're much better off writing a - (NSArray *)arrayByRandomlyOrderingObjects in an NSArray category, and then calling [[mySet allObjects] arrayByRandomlyOrderingObjects];. Bob On 25 May 2010, at 17:54, Dave DeLong wrote: Ah, I see; you don't want to provide the same object twice in a row. If that's the case, is it really random? ;) Dave On May 25, 2010, at 10:52 AM, Dave DeLong wrote: What about something like: @implementation NSSet (Random) - (id) randomObject { NSArray * allObjects = [self allObjects]; if ([allObjects count] == 0) { @throw ...; } return [allObjects objectAtIndex:(arc4random() % [allObjects count])]; } @end ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/tom.davie%40gmail.com This email sent to tom.da...@gmail.com ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: -[NSMutableSet randomObject]
On May 25, 2010, at 11:49 AM, Michael A. Crawford wrote: // If the array is empty, throw an exception. The caller should know better. // If there is only one, return object zero every time. // If there are only two, alternate with every access. // If there are three or more, randomize but never provide the same object // twice in a row. These are definitely strange rules... please note the following which describes basically all rules where n 1 In your starting state, nothing is picked. You then pick something at random from the set. But, that item is not placed back in the set. The 2nd pick comes from the new set. The original item that was picked is now put back into the set. So part of what's going on is a pick without replacement as well as pick with replacement. Having said that, depending upon your needs, I highly recommend the Mersenne Twister algorithm for your psuedo-random generator. Depending upon speed constraints, you may also want to experiment with a Fisher-Yates shuffle of the array, then grab the 0th element as the next random object. ___ Ricky A. Sharp mailto:rsh...@instantinteractive.com Instant Interactive(tm) http://www.instantinteractive.com ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: -[NSMutableSet randomObject]
On May 25, 2010, at 9:49 AM, Michael A. Crawford wrote: // If the array is empty, throw an exception. The caller should know better. // If there is only one, return object zero every time. // If there are only two, alternate with every access. // If there are three or more, randomize but never provide the same object // twice in a row. I don’t think you can provide this behavior as a category, because it requires extra state: each call has to remember what object was returned by the previous call. That state is per-object so it would need to live in the object. But categories don’t give you extra instance variables*. Even if you could put state into the object, I don’t think it’s a good design — what if you ended up with two clients that wanted to get random access to the same set and interleaved their calls? It sounds like what you want is the iterator (aka enumerator) design pattern, where you create a separate lightweight object that returns the “next” item each time it’s called. You can then put the state in the iterator. —Jens * I know there are ways of doing this; but I still think it’s a bad idea, as the next sentence explains.___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com