基本上我选择一个 0-24 之间的随机数:
Math.floor(Math.random() * myArray.length); // myArray contains 25 items
假设它是 8。现在我想得到另一个 0-24 范围内的数字,但这一次,我不想要 8。下一次,我可能会掷出 15。现在我想再次掷出,但我不想要 8 或 15。我现在处理这个问题的方法是使用 do while 循环,如果数字相同,我就重新掷出。
这是我作业的一小部分,事实上,我已经让它满足了所有要求,所以我想你可以说这是为了我个人的利益,这样我就可以正确地写这个,而不是最终陷入“每日的wtf” ”。
Basically I pick a random number between 0-24:
Math.floor(Math.random() * myArray.length); // myArray contains 25 items
Lets say it comes out to be 8. Now I want to get another number in the same range 0-24 but this time, I do not want an 8. The next time, I might roll a 15. Now I want to roll again but I don't want an 8 or 15. The way I am handling this now is by using do while loops and if the number comes out the same, I just reroll.
This is a small portion of my homework and I, in fact, have it working to meet all the requirements so I guess you could say this is for my own personal benefit so I can write this properly and not end up on "the daily wtf".
发布评论
评论(11)
设置一个包含所有值的数组(如果您只处理较小的数字,例如示例中的 25,这只是一个有效的选项),如下所示:
然后,选择 0 到 0 之间的随机数数组长度:
从数组中删除该索引号:
Javascript splice() 从数组中删除索引项并将该项作为数组返回。非常适合您的使用。
从卷中取出第一个索引,因为无论如何我们只切掉 1 个:
根据需要继续执行任意数量的卷。另外,您可能希望将原始数组存储为副本,以便可以轻松“重置”数字。
Set an array with all the values (this is only a valid option if you're only doing small numbers, like the 25 in your example), like this:
then, pick a random number between 0 and the array length:
remove that index number from the array:
Javascript splice() removes indexed items from an array and returns the item(s) as an array. Perfect for your use.
Grab the first index from the roll, since we only cut 1 out anyway:
Keep doing for as many rolls as you want. Also, you might want to store the original array as a copy so that you can "reset" the numbers easily.
这很容易,伙计们。您不希望对此进行递归。这些答案真的很糟糕。理想情况下,您也不想对数组进行硬编码。
现在使用上面函数返回的值从您想要的任何数组中选择一个元素,就像这样:
就是这样。如果您想排除多个值,那么您必须使其更加复杂,但对于排除一个值,这很有效。对此的递归解决方案是矫枉过正并且是一个坏主意。
我还没有测试过这一点,但要排除多个元素,请尝试以下操作:
上述方法听起来与OP的原始方法并没有太大不同。此方法可以正常工作,因为它不会以有偏差的方式从数组中进行采样。
This is easy guys. You do not want recursion for this one. These answers are really bad. Ideally you do not want to hardcode the array, either.
now use the value returned from the above function to choose an element from whatever array you want, just like so:
that's it. if you wanted to exclude more than value, then you would have to make this more sophisticated, but for excluding one value, this works well. A recursive solution for this is overkill and a bad idea.
I haven't tested this, but to exclude more than one element, try this:
The above method does not sound too different from the OP's original method. This method works properly because it does not sample in a biased way from the array.
假设您需要从
1...5
范围内选择一个随机数并排除值2, 4
那么:1 范围内选择一个随机数...3
Suppose you need to choose a random number from the range
1...5
and exclude the values2, 4
then:1...3
这是没有递归且没有创建巨大数组的示例:
This is example without recursion and without creating a huge array:
嗯:-?从数组中随机获取项目并确保它们都是唯一的最快方法是:
Hmz :-? Fastest way to randomly get items from an array and ensure they're all unique would be:
刚刚发现自己处于一种情况,我需要为每个游戏坐标生成一个很长范围内的随机数,但不包括一些已经采用的坐标。
正如您可以想象的那样,重新计算发生在帧之间(理想情况下在 10-14 毫秒内),因此使用递归、while 循环或生成极长数组甚至不是一个选项。
感谢 Salman A 和 Sebastian Umiński 展示了另一种更高效的解决问题的方法。
这是我修改后的 ES6 函数,我希望它能对我遇到的情况有所帮助:)
Just found myself in a situation where I needed to generate a random number in a really long range, for each game coordinate, BUT excluding some coordinates that are already taken.
As you can imagine recalculation happens between frames (within 10-14ms ideally), so using recursion, while-loop or generating extremely long array are not even an options.
Thanks Salman A and Sebastian Umiński for showing another more performant way of solving the problem.
So here's my revised ES6 function and I hope it helps somebody in a situation that I found myself in :)
我确信有几种方法可以做到这一点,但是您可以将所有数字放入类似堆栈之类的东西中,将其全部打乱,然后从其中弹出以获取随机数。或者,每次随机查找它并将其从堆栈中删除。
I'm sure there are a few ways to do this, but you could put all the numbers into something like a stack, jumble it all up and then pop off of it to get your random numbers. Or, randomly seek into it every time and remove it from the stack.
步骤1>创建一个阵列check_array填充数组中的值,该值超出了随机数的范围(如果要在0-25中生成数字,则用26填充26)
step2->生成一个随机数并将其添加到Random_Array,并将其添加到check_array
那就是
step3->生成一个新的随机数,然后走过check_array,如果您发现26,则忽略,否则,如果您发现重复,然后重新生成一个随机数,然后再次继续步骤3,直到找到一个唯一的随机数!
step 1> create an array CHECK_ARRAY fill the array with value which is out of the range of your random number [fill it with 26 if you want to generate number within 0-25]
step2-> generate a random number and add it to RANDOM_ARRAY and also add it to the CHECK_ARRAY
that is
step3-> generate a new random number and go though the CHECK_ARRAY, if you found 26 then ignore, else if you found duplicate then re-generate a random number and continue step 3 again until you found an unique random number !
这是一个经过测试且简单的解决方案:
在其他解决方案中,我相信他们忘了搜索索引。
Here is a tested and simple solution:
In other solutions i believe they forgot to search for the index.
@alex chebotarsky 。
经过一些单元测试后,我发现一些额外的检查是审慎的:
如果您有兴趣,则进行单位测试:
此功能是单位测试的依赖性:
如果您对
test.test.repeats.repeats,它是一个自定义
jest
扩展:./jest.extends.ts
它在失败的测试中打印此内容:
./jest.config.js< /code>
在测试前确保运行扩展文件,并在
jest.d.ts
和tsconfig.json
中包括Jest自定义类型,如果使用TypeScript。Jest.d.ts
Adding up on the great answer by @Alex Chebotarsky.
After some unit testing I found that some additional checks are prudent:
If you are interested, here goes the unit test:
This function is a dependency for the unit test:
And if you are even more interested about the
test.repeats
, it is a customjest
extension:./jest.extends.ts
It prints this on failing tests:
./jest.config.js
Make sure to run the extension file before tests and include the jest custom types in
jest.d.ts
andtsconfig.json
if using typescript.jest.d.ts