0

I found this post: What's the Best Way to Shuffle an NSMutableArray?

And as i try to deploy this in my own code, I cant get it working...

Can anyone help me to resolve this code?

To me it looks like the shuffle function is not called..?

here is my code:

// // shuffle2ViewController.h // shuffle2

#import

@interface shuffle2ViewController : UIViewController {
NSMutableArray *puzzles; 
int *randomSort;
}

- (void)shuffle;
@end

//=============================

// shuffle2ViewController.m

´#import "shuffle2ViewController.h"

@implementation shuffle2ViewController

(void)viewDidLoad { 
[super viewDidLoad];

NSMutableArray *puzzles = [NSMutableArray arrayWithObjects:@"1",@"2",@"3", @"4",@"5",@"6",@"7",@"8",@"9", @"10",@"11",@"12", nil];

// Call the shuffle function
[self shuffle];

// print to log

int i;

NSLog(@"NEW OLD");

NSLog(@"=================");

for (i = 0; i < 12; ++i) NSLog(@" %2i %@", i + 1, [puzzles objectAtIndex:i]); }

int randomSort(id obj1, id obj2, void *context ) {
// returns random number -1 0 1
return (random()%3 - 1); }

(void)shuffle { // call custom sort function

[puzzles sortUsingFunction:randomSort context:nil]; 
}

Giving this result:

NEW OLD
=================
1 1
2 2
3 3
4 4
5 5
6 6
7 7
8 8
9 9
10 10
11 11
12 12
Community
  • 1
  • 1
  • 2
    Nooooooo!!!! Don't use `-sort` to implement shuffling. Use Fisher-Yates shuffle, which runs in O(n) instead of O(n log n) and possibly generate more uniform result (http://en.wikipedia.org/wiki/Fisher–Yates_shuffle). – kennytm Mar 12 '10 at 17:52
  • Better Wikipedia link: http://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle – Peter Hosey Mar 13 '10 at 09:04
  • 1
    steffen Myklebust: Why not use the top-rated answer from that question? http://stackoverflow.com/questions/56648/whats-the-best-way-to-shuffle-an-nsmutablearray/56656#56656 It's not ideal (`int` is usually the wrong type to use in Cocoa), but it's better than basing your shuffle on an unidentified sort. – Peter Hosey Mar 13 '10 at 09:08
  • Thanks all for input. Here is what I ended up with to get the result i wanted. -(void)shuffle { NSUInteger n = [puzzles count]; while(1 < n) { NSUInteger k = random() % n; n--; [puzzles exchangeObjectAtIndex:n withObjectAtIndex:k]; } NSUInteger count = [puzzles count]; for (NSUInteger i = 0; i < count+1; ++i) { // Select a random element between i and end of array to swap with. int nElements = count - i; int n = ( arc4random() % nElements) + i; [puzzles exchangeObjectAtIndex:i withObjectAtIndex:n]; } } – Steffen Myklebust Mar 14 '10 at 21:11

2 Answers2

4

Your problem is that you're redeclaring the puzzles array. It's an ivar on the class, but since you've got the NSMutableArray * puzzles = ... in your viewDidLoad method, it's overriding the instance variable. If you were to NSLog(@"%@", puzzles); in your shuffle method, you'll see that it logs (null).

The simple fix is to delete the NSMutableArray * in your viewDidLoad method.

EDIT

Also (as Peter mentions in the comments) don't forget to retain the array.

Dave DeLong
  • 242,470
  • 58
  • 448
  • 498
  • 2
    Simply deleting the type, and thereby changing the declaration to a statement, would cause an under-retention problem, since the expression on the right side of the = does not alloc or retain the array. – Peter Hosey Mar 13 '10 at 09:06
0

Here is what I use:

- (void) shuffle
{
    // Use the Fisher-Yates shuffle method (http://en.wikipedia.org/wiki/Fisher-Yates_shuffle):
    /*
     Random rng = new Random();   // i.e., java.util.Random.
     int n = array.length;        // The number of items left to shuffle (loop invariant).
     while (n > 1) 
     {
     int k = rng.nextInt(n);  // 0 <= k < n.
     n--;                     // n is now the last pertinent index;
     int temp = array[n];     // swap array[n] with array[k] (does nothing if k == n).
     array[n] = array[k];
     array[k] = temp;
     }
     */

    NSUInteger n = [_cards count];
    while(1 < n) {
        NSUInteger k = random() % n;
        n--;
        [_cards exchangeObjectAtIndex:n withObjectAtIndex:k];
    }
}
sbooth
  • 16,646
  • 2
  • 55
  • 81