NSMutableSet 和 NSArray 排序,如何保持一致?

发布于 2024-09-06 08:16:13 字数 2110 浏览 2 评论 0原文

我正在尝试以随机、不重复的顺序创建一组对象。按照此处的建议使用 NSMutableSet 进行繁重的工作:如何检查重复数组中的数字?

我在创建后将它们转储到 NSArray 中以访问它们,但 NSArray 不会保持我将它们放入 NSMutableSet 中的顺序。更令人困惑的是它不一致。

我的代码:

NSArray *puzzleImages = [[NSArray alloc] initWithObjects:@"elephant.png", @"gorilla.png", @"lion.png", @"zebra.png", @"flamingo.png", @"hyena.png", @"seal.png", @"hippo.png", @"rhino.png", @"tiger.png", @"macaw.png", @"bear.png", nil];

NSArray *puzzleSounds = [[NSArray alloc] initWithObjects:@"elephant", @"gorilla", @"lion", @"zebra", @"flamingo", @"hyena", @"seal", @"hippo", @"rhino", @"tiger", @"macaw", @"bear", nil];

NSMutableSet *aImages1 = [NSMutableSet setWithCapacity:2];
NSMutableSet *aSounds1 = [NSMutableSet setWithCapacity:2];
NSMutableSet *aValues1 = [NSMutableSet setWithCapacity:2];
while([aImages1 count]<=1){
  int Randnum1 = arc4random() % 11;
  [aImages1 addObject:[puzzleImages objectAtIndex:Randnum1]];
  [aSounds1 addObject:[puzzleSounds objectAtIndex:Randnum1]];
  [aValues1 addObject:[NSNumber numberWithInt:Randnum1]];
  NSLog(@"image:%@, sound:%@, value:%@",[puzzleImages objectAtIndex:Randnum1],[puzzleSounds objectAtIndex:Randnum1],[NSNumber numberWithInt:Randnum1]);
} 

NSArray *arrayOfImages1 = [aImages1 allObjects];
NSLog(@"arrayOfImages1: %@",arrayOfImages1);

NSArray *arrayOfSounds1 = [aSounds1 allObjects];
NSLog(@"arrayOfSounds1: %@",arrayOfSounds1);

NSArray *arrayOfValues1 = [aValues1 allObjects];
NSLog(@"aValues1: %@",aValues1);

这是我的输出:

2010-06-20 16:13:14.572 MatchGame[22675:207] image:lion.png, sound:lion, value:2
2010-06-20 16:13:14.574 MatchGame[22675:207] image:macaw.png, sound:macaw, value:10
2010-06-20 16:13:14.575 MatchGame[22675:207] arrayOfImages1: (
"lion.png",
"macaw.png")
2010-06-20 16:13:14.575 MatchGame[22675:207] arrayOfSounds1: (
macaw,
lion)
2010-06-20 16:13:14.576 MatchGame[22675:207] aValues1: {(
2,
10)}

金刚鹦鹉的声音到底是如何高于狮子的声音的?当然,这种情况并不总是发生,但一旦发生就会破坏游戏。我确信我错过了一些愚蠢的事情,但我花了足够的时间试图自己解决它。

I'm trying to make an array of objects in random, non repeating order. Using NSMutableSet for the heavy lifting as recommended here: How to check repetition of numbers in an array?

I'm dumping them into an NSArray after creation to access them, but the NSArray doesn't stay in the order I placed them in the NSMutableSet. Making it more confusing is that it's not consistent.

My code:

NSArray *puzzleImages = [[NSArray alloc] initWithObjects:@"elephant.png", @"gorilla.png", @"lion.png", @"zebra.png", @"flamingo.png", @"hyena.png", @"seal.png", @"hippo.png", @"rhino.png", @"tiger.png", @"macaw.png", @"bear.png", nil];

NSArray *puzzleSounds = [[NSArray alloc] initWithObjects:@"elephant", @"gorilla", @"lion", @"zebra", @"flamingo", @"hyena", @"seal", @"hippo", @"rhino", @"tiger", @"macaw", @"bear", nil];

NSMutableSet *aImages1 = [NSMutableSet setWithCapacity:2];
NSMutableSet *aSounds1 = [NSMutableSet setWithCapacity:2];
NSMutableSet *aValues1 = [NSMutableSet setWithCapacity:2];
while([aImages1 count]<=1){
  int Randnum1 = arc4random() % 11;
  [aImages1 addObject:[puzzleImages objectAtIndex:Randnum1]];
  [aSounds1 addObject:[puzzleSounds objectAtIndex:Randnum1]];
  [aValues1 addObject:[NSNumber numberWithInt:Randnum1]];
  NSLog(@"image:%@, sound:%@, value:%@",[puzzleImages objectAtIndex:Randnum1],[puzzleSounds objectAtIndex:Randnum1],[NSNumber numberWithInt:Randnum1]);
} 

NSArray *arrayOfImages1 = [aImages1 allObjects];
NSLog(@"arrayOfImages1: %@",arrayOfImages1);

NSArray *arrayOfSounds1 = [aSounds1 allObjects];
NSLog(@"arrayOfSounds1: %@",arrayOfSounds1);

NSArray *arrayOfValues1 = [aValues1 allObjects];
NSLog(@"aValues1: %@",aValues1);

Here's my output:

2010-06-20 16:13:14.572 MatchGame[22675:207] image:lion.png, sound:lion, value:2
2010-06-20 16:13:14.574 MatchGame[22675:207] image:macaw.png, sound:macaw, value:10
2010-06-20 16:13:14.575 MatchGame[22675:207] arrayOfImages1: (
"lion.png",
"macaw.png")
2010-06-20 16:13:14.575 MatchGame[22675:207] arrayOfSounds1: (
macaw,
lion)
2010-06-20 16:13:14.576 MatchGame[22675:207] aValues1: {(
2,
10)}

How the heck did the Macaw sound end up above the lion sound? Course it doesn't always happen, but it breaks the game when it does. I'm sure I'm missing something silly, but spent enough time trying to figure it out on my own.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

猫九 2024-09-13 08:16:13

套装未订购。特别是,您从中获得的顺序将取决于您放入的对象,而不是您添加它们的顺序。 (通常它们是使用某种对象哈希来实现的,尽管我不知道这里是否是这种情况。)

由于您想要保持一堆链接的项目,一个选择是创建一个包含它们的单个对象类所有,并将其存储在集合中。然后您可以将其取出并读取其不同字段。

另一种选择是仅打乱一个索引列表,然后按该顺序访问各种原始数组中的对象。

更新:您链接到的帖子正在解决与您的问题截然不同的问题。就您而言,使用集合排序进行随机化确实是错误的做法,因为排序实际上并不是随机的。正确的做法是打乱单个索引数组,如下所示:

NSMutableArray *indices = [NSMutableArray arrayWithCapacity:11];
for ( int i = 0; i < 11; ++i )
    [indices addObject:[NSNumber numberWithInt:i]];
for ( int i = 0; i < 11; ++i )
    [indices exchangeObjectAtIndex:i withObjectAtIndex:(arc4random() % 11)];

NSLog(@"First random image: %@", [puzzleImages objectAtIndex:[[indices objectAtIndex:0] intValue]]);

等等。您对唯一性的保证来自于这样一个事实:您从列表中的索引 0..10 开始,然后进行洗牌,而不是尝试从可能产生重复项的随机数生成器中构造索引本身。

Sets are not ordered. In particular, the ordering you get out of them will depend on the objects you put in rather than the order you add them. (Often they are implemented using some kind of object hash, though I don't know offhand if that's the case here.)

Since you want to keep a bunch of items linked, one option would be to make a single object class that contains them all, and store that in the set. You can then get it out and read off its different fields.

Another option would be just to scramble one list of indices and then access the objects in your various original arrays in that order.

Update: the post you link to is solving a rather different problem from yours. In your case, using set ordering to randomise is really the wrong thing to do, because the ordering will not be actually random. The right thing to do is to scramble a single array of indices, something like this:

NSMutableArray *indices = [NSMutableArray arrayWithCapacity:11];
for ( int i = 0; i < 11; ++i )
    [indices addObject:[NSNumber numberWithInt:i]];
for ( int i = 0; i < 11; ++i )
    [indices exchangeObjectAtIndex:i withObjectAtIndex:(arc4random() % 11)];

NSLog(@"First random image: %@", [puzzleImages objectAtIndex:[[indices objectAtIndex:0] intValue]]);

And so on. Your guarantee of uniqueness comes from the fact that you start out with indices 0..10 in the list and then shuffle, rather than trying to conjure the indices themselves from a random number generator that may produce duplicates.

自演自醉 2024-09-13 08:16:13

集合没有顺序 - 因此如果您想让事物保持添加的顺序,则需要使用数组。

同样在这种情况下,如果原始数组中有两个相同的项目,您将从集合中获得的元素会减少。

Sets have no order - so if you want to keep things in the same order you added you need to use Arrays.

Also in this case if you have two items the same in your original array you will get less elements out of the set.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文