如何不重复地从数组中获取元素?

时间:2019-05-30 08:38:45

标签: javascript

如何不重复地从数组中获得5个元素?

我正在尝试使用Tumult Hype创建在线版本的故事骰子。我需要做的就是从一个数组中选择5个图像名称,而无需重复。但是我只是无法正常工作。

我尝试从其他stackoverflow答案中借用代码,但无法正常工作。

下面的代码当前正在工作,但是让我重复了。如何修补它以消除重复?

(您可以在此处查看它的运行情况:https://davebirss.com/storydice/

我知道它可能很冗长和不雅。恐怕我只说pidgin javascript。而我现在想做的事超出了我的能力。

非常感谢您的帮助。

var diceRoll = ['${resourcesFolderName}/story_dice1.png',
        '${resourcesFolderName}/story_dice2.png',
        '${resourcesFolderName}/story_dice3.png',
        ...,
        '${resourcesFolderName}/story_dice51.png']

function choose(n, arr) {
    while (arr.length > n) {
        var del = Math.floor(Math.random() * arr.length);
        arr = arr.filter(function(item, i) {
            return i !== del;
        });
    }
    return arr;}

var result1 = [choose(1, diceRoll)];
var result2 = [choose(1, diceRoll)];
var result3 = [choose(1, diceRoll)];
var result4 = [choose(1, diceRoll)];
var result5 = [choose(1, diceRoll)];

hypeDocument.getElementById("dice1").innerHTML = "<img src='"+result1+" 'height='125' width='125'>";
hypeDocument.getElementById("dice2").innerHTML = "<img src='"+result2+" 'height='125' width='125'>";
hypeDocument.getElementById("dice3").innerHTML = "<img src='"+result3+" 'height='125' width='125'>";
hypeDocument.getElementById("dice4").innerHTML = "<img src='"+result4+" 'height='125' width='125'>";
hypeDocument.getElementById("dice5").innerHTML = "<img src='"+result5+" 'height='125' width='125'>";

更新

谢谢大家的帮助。我确信所有答案都是不错的,但是U25lYWt5IEJhc3RhcmQg中的代码段是我成功整合的代码。记录下来,这就是我的做法:

const rollTheDice = (arr, n) => {
  const randomN = [];
  while(randomN.length < n){
    const randomIndex = Math.floor(Math.random()*arr.length);
    randomN.push(arr[randomIndex]);
    arr.splice(randomIndex, 1);
  }
  return randomN;}

var result1 = (rollTheDice(images,1)); 
var result2 = (rollTheDice(images,1));
var result3 = (rollTheDice(images,1));
var result4 = (rollTheDice(images,1)); 
var result5 = (rollTheDice(images,1));

我一直在重复加载页面,还没有发现任何重复。完美!

5 个答案:

答案 0 :(得分:2)

您可以获取一组索引,然后检查索引是否存在,然后获取新索引或推送该索引。

var length = 51,  // your count of items
    indices = [], // the result set with indices
    count = 5,    // the amount of wanted indices
    random;       // guess what?
    
while (indices.length < count) {                 // check length
    random = Math.floor(Math.random() * length); // get random value
    if (indices.includes(random)) continue;      // continue if already selected
    indices.push(random);                        // if not take it
}

console.log(indices);

答案 1 :(得分:0)

  1. 复制diceRoll数组(diceRollCopy)。
  2. 使用新数组(diceRollCopy)作为select方法的参数。
  3. 每当您得到一个 使用select方法的结果从Copy数组中删除该结果 (diceRollCopy)。
  4. 您需要将diceRollCopy重置为diceRoll 在访问每组结果之后。

答案 2 :(得分:0)

复制它,然后将副本随机播放,并每次从数组中删除第一个元素:

const copy = [...diceRoll].sort(e => 0.5 - Math.random());

在您选择的功能中:

const chosen = copy.shift();

答案 3 :(得分:0)

我想,这里最棘手的部分是不要浪费性能,将可能的选项限制为以前未选择的选项:

//div[@id='page-segment-values']/div[@class='keyvals']/@data-content_published_date

答案 4 :(得分:0)

您想要一个随机排列,其中所有元素都是uniq并来自一个数据集,这是我的实现:

var array = [1, 2, 3, 4, 5, 6];

/**
 * uniqGet
 * @param {*} array source array
 * @param {*} num how many elements to get
 */
function uniqGet(array, num) {
  if (array.length < num) {
    throw new Error("num should less than options");
  }
  let res = [];
  while (num > 0) {
    let index = Math.floor(Math.random() * array.length);
    res.push(array[index]);
    array.splice(index, 1);
    num--;
  }
  return res;
}

let result = uniqGet(array, 3); // [x, y, z]