如何在不替换条件的情况下随机化?
Posted
技术标签:
【中文标题】如何在不替换条件的情况下随机化?【英文标题】:How to randomize without replacement with conditions? 【发布时间】:2021-07-16 19:15:40 【问题描述】:我有许多嵌入的图像,我将它们随机化 4 次而不进行替换(一旦看到图像,您将无法再次看到它)。我想添加一个条件,表明无法看到一组附加图像(不仅是先前选择的图像)。这些图片与所选图片具有相似的特征。
演示:
假设我有以下变量数组: BF1, BA1, BF2, BA2, BF3, BA3
我想从数组中随机抽取 3 个变量(图像)而不进行替换,并且我还希望从下一个数组中删除编号为 2(相同集合)的变量。因此,如果第一个绘制的 var 是 BF2,下一个绘制将来自以下数组:
BF1, BA1, BF3, BA3(这些选项只能随机出现一个)
现在假设我画了 var BF1,那么下一组可能的 var 将是:
BF3,BA3。
我希望这是有道理的.. 这是我目前没有替换的绘图代码:
function shuffle(array)
var counter = array.length,
temp, index;
while (counter > 0)
index = Math.floor(Math.random() * counter);
counter = counter-1;
temp = array[counter];
array[counter] = array[index];
array[index] = temp;
return array;
var myArray=[BF1,BA1,BF2, BA2, BF3,BA3, BA4, BF4, BA5, BF5, BF6, BA6, BF7, BA7, BA8, BF8, BA9, BF9,
BF10, BA10, BA11, BF11, BA12, BF12, BA13, BF13, BA14, BF14, BA15, BF15, BA16, BF16, BA17, BF17,
BA18, BF18, BA19, BF19, BA20, BF20, BA21, BF21, BF22, BA23, BF23, BA24, BF24, BA25, BF25, BA26,
BF26, BA27, BF27, BA28, BF28, BA29, BF29, BA30, BF30, BA31, BF31, BA32, BF33, BA33, BA34, BF35,
BA35, BA36, BF36];
shuffle(myArray)
【问题讨论】:
过滤和结束 【参考方案1】:您绝对可以通过多种方式实现这一点,但无论您使用什么,您都需要以某种能力执行以下 3 个步骤(我将它们分成单独的方法,但您可以根据需要将它们组合起来)看合适):
-
随机播放列表
选择一个项目
过滤掉与pick匹配的项目(在本例中为相同编号的项目)
您已经涵盖了随机播放程序,因此只剩下选择和过滤器。
对于选择,我只是使用Math.random
来随机抽取列表中的一个成员:
return array[Math.floor(Math.random() * array.length)];
对于过滤器,我使用Array.prototype.filter
拉出所需的项目。在这种情况下,使用字符串,我从字符串中解析出数字,然后删除数组中与上次选择的数字相同的所有项目:
return array.filter(el => +el.match(/\d+/).join() != +picked.match(/\d+/).join());
但是对于实际图像,您只需将其替换为您阅读图像标签的方式即可。
示例
这是完整的工作示例,首先是选择列表,然后是一个排序数组,显示它们都被使用了。
var imageList = ['BF1', 'BA1', 'BF2', 'BA2', 'BF3', 'BA3', 'BA4', 'BF4', 'BA5', 'BF5', 'BF6', 'BA6', 'BF7', 'BA7', 'BA8', 'BF8', 'BA9', 'BF9', 'BF10', 'BA10', 'BA11', 'BF11', 'BA12', 'BF12', 'BA13', 'BF13', 'BA14', 'BF14', 'BA15', 'BF15', 'BA16', 'BF16', 'BA17', 'BF17', 'BA18', 'BF18', 'BA19', 'BF19', 'BA20', 'BF20', 'BA21', 'BF21', 'BF22', 'BA23', 'BF23', 'BA24', 'BF24', 'BA25', 'BF25', 'BA26', 'BF26', 'BA27', 'BF27', 'BA28', 'BF28', 'BA29', 'BF29', 'BA30', 'BF30', 'BA31', 'BF31', 'BA32', 'BF33', 'BA33', 'BA34', 'BF35', 'BA35', 'BA36', 'BF36'];
var selection = imageList.slice();
var picked = [];
function shuffle(array)
var counter = array.length, temp, index;
while (counter > 0)
index = Math.floor(Math.random() * counter);
counter = counter - 1;
temp = array[counter];
array[counter] = array[index];
array[index] = temp;
return array;
function pick(array)
return array[Math.floor(Math.random() * array.length)];
function filterPicked(picked, array)
return array.filter(el => +el.match(/\d+/).join() != +picked.match(/\d+/).join());
while (selection.length)
// 1. Shuffle
shuffle(selection);
// 2. Pick
picked.push(pick(selection));
// 3. Filter
selection = filterPicked(picked[picked.length-1], selection);
console.log(`Picks: [$picked.join(', ')]`);
console.log(`Sorted picks: [$picked.sort((a, b) => +a.match(/\d+/).join() - +b.match(/\d+/).join()).join(', ')]`);
一步一步
-
随机排列选择数组(完整数组或所有选择的副本)
从选择数组中选择一个项目,将其推送到选择数组中
过滤选择数组以删除匹配最后一个选择的项目
对每个新过滤的数组重复 1-3 次,直到没有选择余下
【讨论】:
【参考方案2】:您可以使用循环和随机数对数组进行洗牌,然后在另一个循环中提取结果数组中的第一个图像,在字符串末尾使用数字过滤数组
var myArray="BF1, BA1, BF2, BA2, BF3, BA3, BA4, BF4, BA5, BF5, BF6, BA6, BF7, BA7, BA8, BF8, BA9, BF9, BF10, BA10, BA11, BF11, BA12, BF12, BA13, BF13, BA14, BF14, BA15, BF15, BA16, BF16, BA17, BF17, BA18, BF18, BA19, BF19, BA20, BF20, BA21, BF21, BF22, BA23, BF23, BA24, BF24, BA25, BF25, BA26, BF26, BA27, BF27, BA28, BF28, BA29, BF29, BA30, BF30, BA31, BF31, BA32, BF33, BA33, BA34, BF35, BA35, BA36, BF36";
function shuffle(a)
for (let i = a.length - 1; i > 0; i--)
const j = Math.floor(Math.random() * (i + 1));
[a[i], a[j]] = [a[j], a[i]];
return a;
const arr = shuffle(myArray.split(','));
function draw(a, times)
let res =[]
for (let i = 1; i <= times; i++)
let str = a[0]
res.push(str)
a = a.filter(a => parseInt(a.match(/\d+$/)[0], 10) !== parseInt(str.match(/\d+$/)[0], 10))
return res
console.log(draw(arr, 4))
【讨论】:
以上是关于如何在不替换条件的情况下随机化?的主要内容,如果未能解决你的问题,请参考以下文章
如何在不使用左连接的情况下根据“OR”条件对数据框进行子集化? [复制]