0

Sorry for my bad English, I'm argentinian. I have a question, I am makin a trivia application and logically it doesn't have to re-ask the same. I have 30 questions and this is my code:

-(IBAction)randomear{
    random1=arc4random() % 30;
    if (random1 == 0)
    {
        labelpregunta.text = @"Las ovejas pueden nadar?";
    }
    if (random1 == 1)
    {
        labelpregunta.text = @"Con que se tiñe la lana de negro?";
    }
    if (random1 == 2)
    {
        labelpregunta.text = @"De que material es el mejor casco?";
    }
    if (random1 == 3)
    {
        labelpregunta.text = @"Para fabricar lana necesitas 4 _____";
    }
}

I want to create an NSArray where, if there are a number who repeats, it shuffle again.

How can I do it?

Matt S.
  • 13,305
  • 15
  • 73
  • 129
Dante Puglisi
  • 648
  • 7
  • 24
  • What does "it doesn't have to re-ask the same" mean? Do you mean it should only ask each question once, or do you mean it can ask each question more than once? – N_A Jul 18 '12 at 18:39
  • I don't know objective-c but maybe you can understand the principle with that : http://jsfiddle.net/tx2Bq/1/ – Alexandre Khoury Jul 18 '12 at 18:46
  • possible duplicate of [Non repeating random numbers](http://stackoverflow.com/questions/1617630/non-repeating-random-numbers) – jscs Jul 18 '12 at 18:48

3 Answers3

3

What you want is actually an NSMutableArray (because you will be expanding it as new values come in), and use -indexOfObject to check for previously selected values. Be forewarned, NSMutableArray stores objects of type id, and int is a primitive. You'll need to wrap your random values in an NSNumber before they can be stored. Something like this:

//.h
@property (nonatomic, strong) NSMutableArray *previouslySelectedValues;

//.m
-(IBAction)randomear{
    //I suppose this is an int, right?
    //Supongo que esto es un número entero.
    random1=arc4random() % 30;
    //check if the array can find the object.  It internally uses `-isEqual` in a loop for us
    //estamos comprobando si la matriz se puede encontrar el objeto
    if (![previouslySelectedValues indexOfObject:[NSNumber numberWithInt:random1]]) {
        if (random1 == 0)
        {
            labelpregunta.text = @"Las ovejas pueden nadar?";
        }
        if (random1 == 1)
        {
            labelpregunta.text = @"Con que se tiñe la lana de negro?";
        }
        if (random1 == 2)
        {
            labelpregunta.text = @"De que material es el mejor casco?";
        }
        if (random1 == 3)
        {
            labelpregunta.text = @"Para fabricar lana necesitas 4 _____";
        }

        //et cetera/ etcétera

        //add the object because it doesn't exist and we don't want to select it again.
        //Añadir el objeto a la matriz debido a que es nuevo
        [previouslySelectedValues addObject:[NSNumber numberWithInt:random1]];
    }
    else {
        //do nothing, or use the below pick again if you want
        //No hacer nada, o utilizar el método de abajo para elegir otro número

        //[self randomear];
        return;
    }
}
CodaFi
  • 43,043
  • 8
  • 107
  • 153
1
    // You store your strings here
    static NSArray *myQuestions = [[NSArray alloc] initWithObjects:
                                          @"Las ovejas pueden nadar?",
                                          @"Con que se tiñe la lana de negro?",
                                          @"De que material es el mejor casco?",
                                          @"Para fabricar lana necesitas 4 _____",nil];
    // Make a copy which is mutable
    NSMutableArray *copy = [NSMutableArray arrayWithArray:myQuestions];
    ...

-(IBAction)randomear{

    // Now select one entry
    random1=arc4random() % [copy count];
    labelpregunta.text = [copy objectAtIndex:random1];
    [copy removeObjectAtIndex:random1];

}
Thorsten S.
  • 4,144
  • 27
  • 41
0

Instead of generating a random number and checking if that number has already been used, I would create an NSMutableArray of the numbers 0 to 29 (each wrapped in an NSNumber) and then randomly shuffle the array using the category supplied by Gregory Goltsov in this SO question whats-the-best-way-to-shuffle-an-nsmutablearray.

Then you just iterate over each NSNumber object from the start of the NSMutable array. i.e.

#import "NSMutableArray_Shuffling.h // From Gregory Goltsov
NSMutableArray* randomNumbers = [[NSMutableArray alloc] init];
for(int i=0; i<30; i++) {
  [randomNumbers addObject:[NSNumber numberWithInt:i]];
}
[randomNumbers shuffle]; // From Gregory Goltsov

...

int lastIndex = 0;

-(IBAction)randomear
{
    if (lastIndex<30) {
        NSNumber* theRandomNumber = [randomNumbers objectAtIndex:lastIndex];
        int theQuestion = [theRandomNumber intValue];
        if (theQuestion == 0)  {
            labelpregunta.text = @"Las ovejas pueden nadar?";
        }
        if (theQuestion == 1) {
            labelpregunta.text = @"Con que se tiñe la lana de negro?";
        }
        if (theQuestion == 2) {
            labelpregunta.text = @"De que material es el mejor casco?";
        }
        if (theQuestion == 3){
            labelpregunta.text = @"Para fabricar lana necesitas 4 _____";
        }

        //et cetera/ etcétera    
        lastIndex++;
    } else {
        // No more questions
    }
}

However, it may be better to fill the array with a series of objects that contains both the question and the answer for a single question. i.e.

@interface aQuestion : NSObject
@property (nonatomic, string) NSString* question;
@property (nonatomic, string) NSString* answer;
-(void)initWithQuestion:(NSString)aQuestion and:(NSString) anAnswer;
-(BOOL)isCorrectAnswer(NSString testAnswer);
@end

@implementation aQuestion
-(void)initWithQuestion:(NSString*)aQuestion and:(NSString*) anAnswer
{
  if(!(self=[super init])) return self;

  question = aQuestion;
  answer = anAnswer;

  return self;
}

-(BOOL)isCorrectAnswer(NSString testAnswer)
{
  [answer isEqualToString:testAnswer];
}
@end

...
#import "NSMutableArray_Shuffling.h // From Gregory Goltsov
NSMutableArray* questions = [[NSMutableArray alloc] init];

[questions addObject:[[aQuestion alloc] initWithQuestion:@"Question 1" and:@"Answer 1"]];
[questions addObject:[[aQuestion alloc] initWithQuestion:@"Question 2" and:@"Answer 2"]];
[questions addObject:[[aQuestion alloc] initWithQuestion:@"Question 3" and:@"Answer 3"]];
[questions addObject:[[aQuestion alloc] initWithQuestion:@"Question 4" and:@"Answer 4"]];
[questions shuffle]; // From Gregory Goltsov

...
for(int i=0; i<[questions count]; i++) {
   aQuestion* theQuestion = [questions objectAtIndex:i];

   // Ask theQuestion.question
   labelpregunta.text = theQuestion.question;

   ...

   // wait for theAnswer

   ....

   NSString theAnswer = labelrespuesta.text;

   if ([theQuestion isCorrectAnswer:theAnswer]) {
      // You win!!!!!!!
   }
}

// No more questions

Edit

I initially said Kristopher Johnson's answer, but I really meant Gregory Goltsov's answer

(Y mi español es peor que el Inglés)

Community
  • 1
  • 1
Peter M
  • 7,309
  • 3
  • 50
  • 91