【问题标题】:Getting a random object from NSArray without duplication从 NSArray 获取随机对象而不重复
【发布时间】:2013-05-28 11:50:42
【问题描述】:

我有一个带有 17 个对象的 NSArray,如下所示:

NSArray *objArray = [[NSArray alloc]initWithObjects: @"1",@"2",@"3",@"4",@"5",@"6"
,@"7",@"8",@"9",@"10",@"11",@"12",@"13",@"14",@"15",@"16",@"17", nil];

还有一个int,随机数如下:

int random = arc4random()%17+1;

我想从这个NSArray 中获取一个随机对象,而不是重复,即使我关闭了应用程序(可能通过使用NSUserDefaults)。

如果我得到了所有的对象,我想为相同的对象生成一个新的随机序列。

【问题讨论】:

    标签: objective-c cocoa random duplicates nsarray


    【解决方案1】:

    您可以通过制作数组的可变副本来做到这一点,然后从该数组中进行随机选择后,删除相同的对象。当您要保存数组时,请保存可变数组本身,以便在应用程序重新启动时从您离开的地方继续。这个小测试应用程序会这样做,并且只记录随机选择的值:

    - (void)viewDidLoad {
        [super viewDidLoad];
        self.objArray = @[@"1",@"2",@"3",@"4",@"5",@"6",@"7",@"8",@"9",@"10",@"11",@"12",@"13",@"14",@"15",@"16",@"17"];
        self.mut = [self.objArray mutableCopy];
    }
    
    -(IBAction)pickNumber:(id)sender {
        int index = arc4random_uniform(self.mut.count);
         NSLog(@"%@", self.mut[index]);
        [self.mut removeObjectAtIndex:index];
        if (self.mut.count == 0) {
            self.mut = [self.objArray mutableCopy];
            NSLog(@"*******************");
        }
    }
    

    【讨论】:

      【解决方案2】:

      作为起点,您可以对数组进行洗牌:

      + (NSArray *)arrayByShufflingArray:(NSArray *)array
      {
          // Fisher-Yates algorithm
          NSMutableArray *result = [array mutableCopy];
          NSUInteger count = [result count];
          for (NSInteger i = ((NSInteger) count) - 1; i > 0; i--) {
              NSUInteger firstIndex = (NSUInteger)i;
              NSUInteger secondIndex = arc4random() % (NSUInteger)(i + 1);
      
              [result exchangeObjectAtIndex:firstIndex withObjectAtIndex:secondIndex];
          }
      
          return result;
      }
      

      遍历每个打乱的元素,当你到达最后,重新打乱。

      当一个 shuffle 的最后一个项目与下一个 shuffle 的第一个项目相同时,仍然可能会连续选择一个项目。如果你想避免这种情况,你必须添加一些额外的代码。

      【讨论】:

      • TI 尝试了这个想法,但我有重复的对象被调用,顺便说一句,我的一个对象“XXX”被这种方法连续调用了 3 次
      • @Mutawe 如果对数组进行洗牌,则可以按顺序遍历对象,无需随机选择。
      • 现在我得到了一个洗牌数组,但是我能用它做什么,将它存储在 NSUserDefaults 中??存储从 1 到 17 的计数,如果 count == 17 重新洗牌?
      【解决方案3】:

      只需复制和粘贴

      -(NSMutableArray*)getRandomValueFromArray:(NSMutableArray*)arrAllData randomDataCount:(NSInteger)count {  
       NSMutableArray *arrFilterData = [[NSMutableArray alloc]init];
      for(int i=0; i<count; i++){
      
           NSInteger index = arc4random() % (NSUInteger)(arrAllData.count);
          [arrFilterData addObject:[arrAllData objectAtIndex:index]];
          [arrAllData removeObjectAtIndex:index];
      }
      return arrFilterData;
      }
      

      注意:count = 要从数组中获取的随机值的数量。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-08-25
        • 1970-01-01
        • 1970-01-01
        • 2020-07-17
        • 2013-12-04
        相关资源
        最近更新 更多