xcoderandomnsmutableset

Can't clear/reset NSMutableSet?


This is what I'm trying to do. Get 7 random, non-repeating numbers each time my viewDidLoad starts. I got it to create the randoms, but I've been trying to clear the NSMutableSet when it loads to get a fresh set and I'm having trouble. The NSLog is clearly showing nothing is in the NSMutableSet, but it always comes up with the same numbers in the same order?

// Create set
NSMutableSet *mySet = [NSMutableSet setWithCapacity:6];

// Clear set
NSMutableSet *mutableSet = [NSMutableSet setWithSet:mySet];
[mutableSet removeAllObjects];
mySet = mutableSet;

NSLog(@"mutableSet: %@", mutableSet);  // Shows nothing
NSLog(@"mySet: %@", mySet);  // Shows nothing

// Assign random numbers to the set
while([mySet count]<=6){
    int Randnum = arc4random() % 7+1;
    [mySet addObject:[NSNumber numberWithInt:Randnum]];
}

NSLog(@"mySet1: %@", mySet);  // Always shows 5,1,6,2,7,3,4 ???

Solution

  • An NS(Mutable)Set is an unordered collection, it does not preserve the order of the elements as they were inserted. So your output only shows that the set contains the numbers from 1 to 7.

    You have different options to get your expected output.

    1. Use an NSMutableOrderedSet instead.

    2. Use a set to keep track of the numbers that already occurred, but store the numbers also in an array:

      NSMutableArray *numbers = [NSMutableArray array];
      NSMutableSet *mySet = [NSMutableSet set];
      while ([numbers count] < 6) {
          NSNumber *randNum = @(arc4random_uniform(7) + 1);
          if (![mySet containsObject:randNum]) {
              [numbers addObject:randNum];
              [mySet addObject:randNum];
          }
      }
      NSLog(@"numbers: %@", numbers);
      
    3. For a small set (like 7 numbers in your case), you could simply use an array only:

      NSMutableArray *numbers = [NSMutableArray array];
      while ([numbers count] < 6) {
          NSNumber *randNum = @(arc4random_uniform(7) + 1);
          if (![numbers containsObject:randNum]) {
              [numbers addObject:randNum];
          }
      }
      NSLog(@"numbers: %@", numbers);