从数组中挑选2个随机元素

时间:2012-03-15 12:13:07

标签: javascript jquery

从数组中选择2个唯一随机元素的最有效方法是什么(即,确保未选择相同的元素两次)。

我到目前为止:

var elem1;
var elem2;

elem1 = elemList[Math.ceil(Math.random() * elemList.length)];
do {
  elem2 = elemList[Math.ceil(Math.random() * elemList.length)];
} while(elem1 == elem2)

但这通常会导致我的页面加载。

有更好的解决方案吗?

额外的问题,我如何将其扩展到n元素

9 个答案:

答案 0 :(得分:29)

不要使用循环和比较。代替

  • shuffle数组
  • 采取前两个要素

答案 1 :(得分:5)

http://underscorejs.org/#sample

  

_。sample(list,[n])

     

从列表中生成随机样本。传递一个数字以从列表中返回n个随机元素。否则将返回一个随机项目。

_.sample([1, 2, 3, 4, 5, 6]);
=> 4

_.sample([1, 2, 3, 4, 5, 6], 3);
=> [1, 6, 2]

查看源代码,它使用 shuffle ,就像@ thg435建议一样。

答案 2 :(得分:4)

当列表只包含一个项目时,您的代码将挂起。我建议不要使用==,而是使用===,在这种情况下看起来更合适。

另外,请使用Math.floor代替Math.ceillength属性等于<highest index> + 1

var elem1;
var elem2;
var elemListLength = elemList.length;

elem1 = elemList[Math.floor(Math.random() * elemListLength)];
if (elemListLength > 1) {
    do {
      elem2 = elemList[Math.floor(Math.random() * elemListLength)];
    } while(elem1 == elem2);
}

答案 3 :(得分:3)

关于Rob W告诉你的内容,我将补充一点,不同的解决方案是找到一个随机点,第二点找到一个随机偏移点:

var elem1;
var elem2;
var elemListLength = elemList.length;

var ix = Math.floor(Math.random() * elemListLength);
elem1 = elemList[ix];

if (elemListLength > 1) {
    elem2 = elemList[(ix + 1 + Math.floor(Math.random() * (elemListLength - 1))) % elemListLength];
}

我们加1,因为当前元素无法重新选择并减1,因为已经选择了一个元素。

例如,三个元素(0,1,2)的数组。我们随机选择元素1.现在“好”偏移值为0和1,偏移量0给出元素2,偏移量1给出元素0。

请注意,这将为您提供两个具有不同INDEX的随机元素,而不是使用不同的VALUE!

答案 4 :(得分:2)

如果你想获得n随机元素,你可以创建一个混乱版本的列表,然后返回混洗数组的第一个n元素。

答案 5 :(得分:2)

可以使用内置功能( slicesort )来完成,

var n = 2
    randomItems = array.sort(() => .5 - Math.random()).slice(0, n);

答案 6 :(得分:0)

如果您将数组洗牌并拼接您想要返回的元素数量, 返回值将包含尽可能多的项目, 如果你要求的项目多于阵列中的项目。 您可以使用slice()对实际数组或副本进行随机播放。

Array.prototype.getRandom= function(num, cut){
    var A= cut? this:this.slice(0);
    A.sort(function(){
        return .5-Math.random();
    });
    return A.splice(0, num);
}
var a1= [1, 2, 3, 4, 5];
a1.getRandom(2)
>>[4, 2]

如果要从原始数组中删除所选项目, 这样第二次调用将不包括第一次调用返回的元素, 传递第二个参数:getRandom(3,true);

window.Memry=window.Memry || {};
Memry.a1= [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

Memry.a1.getRandom(3,true);
>>[5,10,7]
Memry.a1.getRandom(3,true);
>>[3,9,6]
Memry.a1.getRandom(3,true);
>>[8,4,1]
Memry.a1.getRandom(3,true);
>>[2]

答案 7 :(得分:0)

在随机排列数组并选择前两个数组时是正确的。
您不需要重新整理整个数组。

只需随机播放前两个!

var arrElm = [1, 2, 3, 4, 5, 6, 7]

var toTake = 2

var maxToShuffle = Math.min(arrElm.length - 1, toTake)

for (let i = 0; i < maxToShuffle; i++) {
  const toSwap = i + Math.floor(Math.random() * (arrElm.length - i))
  ;[arrElm[i], arrElm[toSwap]] = [arrElm[toSwap], arrElm[i]]
}

console.log(arrElm.slice(0, toTake))

基本上与 https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle

除非您洗完足够的物品后才提前退出。

答案 8 :(得分:0)

您可以像这样简单地做

const elements = ['indie hackers', 'twitter', 'product hunt', 'linkedIn'];
const randomIndex = Math.floor(Math.random() * elements.length);
const a = elements[randomIndex];

const filteredElements = [...elements].splice(randomIndex, 1);
const b = filteredElements[Math.floor(Math.random() * elements.length)];

a和b将是您的随机元素。