如何生成一个新的随机数(与之前的随机数不同)

时间:2016-09-04 01:41:26

标签: javascript

我正在尝试更改以下内容(当前从数组中返回一个随机数),以便每个随机数与上一个随机数不同。

function randomize(arr) {
            return arr[Math.floor(Math.random()*arr.length)];
        }

oracleImg = [];
          for (var i=1;i<=6;i++) {
          oracleImg.push(i);
        } 

randOracleImg = randomize(oracleImg);

我尝试了以下内容,但并不总是给我一个与上一个数字不同的数字。

function randomize(arr) {
    var arr = Math.floor(Math.random()*arr.length);
    if(arr == this.lastSelected) {
          randomize();
        }
        else {
            this.lastSelected = arr;
            return arr;
        }
}

我该如何解决这个问题?

4 个答案:

答案 0 :(得分:1)

您现有的函数的递归randomize()调用没有意义,因为您没有通过arr论证,而且您没有做任何事情它的回报价值。该行应该是:

return randomize(arr);

...除了当它到达该行时,您已重新分配arr,以便它不再引用原始数组。使用以下版本中的附加变量应该有效。

请注意,我还添加了一项测试,以确保如果数组只有一个元素,我们会立即返回该项,因为在这种情况下,每次都无法选择不同的项目。 (如果数组为空,则函数返回undefined。)

&#13;
&#13;
function randomize(arr) {
    if (arr.length < 2) return arr[0];
    var num = Math.floor(Math.random()*arr.length);
    if(num == this.lastSelected) {
        return randomize(arr);
    } else {
        this.lastSelected = num;
        return arr[num];
    }
}

document.querySelector("button").addEventListener("click", function() {
    console.log(randomize(["a","b","c","d"]));
});
&#13;
<button>Test</button>
&#13;
&#13;
&#13;

请注意,您的原始函数似乎返回了一个随机数组 index ,但我的答案中显示的代码返回一个随机数组元素

另请注意,您调用函数的方式意味着在函数this中是窗口 - 不确定这是否符合您的意图;它有效,但基本上lastSelected是一个全局变量。

鉴于我并不热衷于不必要地创建全局变量,这里是一个没有全局变量的替代实现,没有递归,因为在我看来,一个简单的while循环是一种更加语义的方式来实现&#34;继续尝试直到 x 发生&#34;:

&#13;
&#13;
var randomize = function () {
    var lastSelected, num;
    return function randomize(arr) {
        if (arr.length < 2) return arr[0];
        while (lastSelected === (num = Math.floor(Math.random()*arr.length)));
        lastSelected = num;
        return arr[num];
    };
}();

document.querySelector("button").addEventListener("click", function() {
    console.log(randomize(["a","b","c","d"]));
});
&#13;
<button>Test</button>
&#13;
&#13;
&#13;

答案 1 :(得分:1)

下面的代码只是一个例子,它将生成99个数字,所有都将是唯一的和随机的(范围是0-1000),逻辑很简单只需在临时数组中添加随机数并比较新的随机数(如果它已经生成)或不。

&#13;
&#13;
var tempArray = [];
var i=0;
while (i != 99) {
  var random = Math.floor((Math.random() * 999) + 0);
  if (tempArray.indexOf(random)==-1) {
        tempArray.push(random);
        i++;
  } else {
    continue;
  }
}
console.log(tempArray);
&#13;
&#13;
&#13;

答案 2 :(得分:1)

如果你想总是从一个数组中返回一个不同的数字,那么就不要随意改组,而是洗牌!*

最简单的公平(真正随机)混洗算法是Fisher-Yates算法。不要做同样的mistake Microsoft did and try to abuse .sort() to implement a shuffle。只需实施Fisher-Yates (otherwise known as the Knuth shuffle)

// Fisher-Yates shuffle:
// Note: This function shuffles in-place, if you don't
//       want the original array to change then pass a copy
//       using [].slice()
function shuffle (theArray) {
    var tmp;
    for (var i=0; i<theArray.length;i++) {
        // Generate random index into the array:
        var j = Math.floor(Math.random()*theArray.length);

        // Swap current item with random item:
        tmp = theArray[i];
        theArray[j] = theArray[i];
        theArray[i] = tmp;
    }
    return theArray;
}

所以就这样做:

shuffledOracleImg = shuffle(oracleImg.slice());

var i=0;

randOracleImg = shuffledOracleImg[i++]; // just get the next image
                                        // to get a random image

您希望如何处理图像耗尽取决于您。像iTunes这样的媒体播放器或iPhone,iPad和iPod上的音乐播放器让用户可以选择从一开始就停止播放或重复播放。一些纸牌游戏软件将重新洗牌并重新开始。

  

*注意:我的一个小小的烦恼是随机化而不是随机播放的音乐播放器软件。随机化是完全错误的事情,因为1.有些实现不会检查下一首歌是否与当前歌曲相同,因此你会播放两首歌曲(你似乎想要避免的)和2.歌曲最终永远不会被播放。从头到尾随机播放和播放洗牌播放列表可以避免这两个问题。 CD播放器制造商做对了。 MP3播放器开发者往往会弄错。

答案 3 :(得分:1)

这是一个版本,它将确保一个始终与最后一个不同的随机数。另外,您可以控制生成的随机值的最大值和最小值。默认值为max:100和min:1

var randomize = (function () {
    var last;
    return function randomize(min, max) {
        max = typeof max != 'number' ? 100 : max;
        min = typeof min != 'number' ? 1 : min;

        var random = Math.floor(Math.random() * (max - min)) + min;
        if (random == last) {
            return randomize(min, max);
        }

        last = random;
        return random;
    };
})();