tags:

views:

203

answers:

1

All examples I find on shuffling arrays are for NSMutableArrays. Copying an NSArray to an NSMutable array, shuffling, then copying back always crashes the application. Is it even possible to shuffle an NSArray?

Anything in objective-c similar to Collections.shuffle() (Java)?

Edit

static NSUInteger random_below(NSUInteger n) {
NSUInteger m = 1;

do {
    m <<= 1;
} while(m < n);

NSUInteger ret;

do {
    ret = random() % m;
} while(ret >= n);

return ret;
}
- (NSArray *)loadAllData{
    XYZAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];

    NSManagedObjectContext *managedObjectContext = appDelegate.managedObjectContext;
    NSFetchRequest *request = [[NSFetchRequest alloc] init]; 
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Quote" inManagedObjectContext:managedObjectContext]; 
    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"id" ascending:YES];  
    NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];   

    [request setSortDescriptors:sortDescriptors];
    [request setEntity: entity]; 

    NSError *myError;   
    NSArray *theResults = [managedObjectContext executeFetchRequest:request error:&myError];

    if (theResults == nil) {
        NSLog(@"Testing: No results found");
    }else {
        NSLog(@"Testing: Results found.");
    }

    [request release];
    [sortDescriptors release];

    for(NSUInteger i = [theResults count]; i > 1; i--) {
        NSUInteger j = random_below(i);
        [theResults exchangeObjectAtIndex:i-1 withObjectAtIndex:j];
    }

    return theResults;
}




warning: 'NSArray' may not respond to '-exchangeObjectAtIndex:withObjectAtIndex:' which crashed the application.     

error: *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[_PFArray exchangeObjectAtIndex:withObjectAtIndex:]: unrecognized selector sent to instance 0x3d35a40
+2  A: 

OK. I think I see a problem. Always look at the error message. I thought you said that you were using NSMutableArrays in this function?

NSArray *theResults = [managedObjectContext executeFetchRequest:request error:&myError];

Change that to

NSMutableArray *theResults = [[managedObjectContext executeFetchRequest:request error:&myError] mutableCopy];

Tell me if it works, and if it doesn't, I'll try and help.

Some more info:

-exchangeObjectAtIndex:withObjectAtIndex:

is a method for a NSMutableArray. You were using a NSArray, they're different classes (NSMutableArray is a subclass (and adds methods that mean you can modify it) of NSArray).

Tom H
I get the data from a SQLite database. I can display all data consecutively without any app crashes. The elements returned are in a NSArray. But when I try any of the NSMutableArray shuffles I see on the internet, the app crashes. I just want to shuffle the NSArray is all.
Oh Danny Boy
Can you edit your post, adding in the shuffling code and how you're using it? That would likely help? It is impossible to shuffle an NSArray, without creating a mutable array from it somehow. So a good thing would be to paste some code and let us help you debug it.
Tom H
It occurred to me to use NSMutableArray, however, I always got this error warning: incompatible Objective-C types initializing 'struct NSArray *', expected 'struct NSMutableArray *'which even after researching I do not completely understand.
Oh Danny Boy
Tom H
Sorry, you are right, I forgot to add "mutableCopy" at the end of it. Wow, thanks.
Oh Danny Boy
No problem... I thought that might be the problem! :)
Tom H