如何在Javascript中从数组中随机选择N项而不重复?

如何在Javascript中从数组中随机选择N项而不重复?,javascript,random,Javascript,Random,我有一个包含一些项目的数组,比如数字: [23,4,67,8,29,46,7,2,98] 如何从数组中选择N个不同的随机数(不多也不少) 预期行为:如果N=3 [4,23,98] accepted [7,67,29] accepted [7,67,7] not accepted 编辑:我终于找到了一个非常好的解决方案。线程已关闭,因此我在这里发布我的解决方案,仅供路过的人使用。 我有一个长为M和N的数组可供选择,因此我制作了一个包含M个数字的数组(indexesArray),应用Fishe

我有一个包含一些项目的数组,比如数字:

[23,4,67,8,29,46,7,2,98]
如何从数组中选择N个不同的随机数(不多也不少)

预期行为:如果N=3

[4,23,98] accepted
[7,67,29] accepted
[7,67,7]  not accepted
编辑:我终于找到了一个非常好的解决方案。线程已关闭,因此我在这里发布我的解决方案,仅供路过的人使用。 我有一个长为M和N的数组可供选择,因此我制作了一个包含M个数字的数组(indexesArray),应用Fisher-Yates算法将与我初始数组的索引相对应的数字洗牌,并从中取出前M项。感谢@ArneHugo为我们指明了正确的道路

var arrayContainingNumbersToChoose=[23,4,67,8,29,46,7,2,98];
var indexesArray=[];
var N=5;
var resultArray=[];

var M=arrayContainingNumbersToChoose.length;

for (let i = 0; i < M; i++) {
   indexesArray.push(i);
} // result like [0, 1, 2, 3, 4, 5, 6, 7, 8]

indexesArray=fisherYatesShuffle(indexesArray); // result like [2, 4, 7, 6, 0, 1, 3, 8, 5]

for (let i = 0; i < N; i++) {
resultArray.push(arrayContainingNumbersToChoose[indexesArray[i]]);
}

console.log(resultArray);

function fisherYatesShuffle(a) {
      var j, x, i;
      for (i = a.length - 1; i > 0; i--) {
          j = Math.floor(Math.random() * (i + 1));
          x = a[i];
          a[i] = a[j];
          a[j] = x;
      }
      return a;
  }
var arraycontainingnumberstochose=[23,4,67,8,29,46,7,2,98];
var indexesArray=[];
var N=5;
var resultArray=[];
var M=数组包含numberstochose.length;
for(设i=0;i0;i--){
j=数学地板(数学随机()*(i+1));
x=a[i];
a[i]=a[j];
a[j]=x;
}
返回a;
}
尝试以下操作:

var-arr=[23,4,67,8,29,46,7,2,98];
var结果=[];
var-map={};
var n=3;
var i=阵列长度;
var计数器=阵列长度+n;
while(result.length!=n){
num=arr[Math.floor(Math.random()*i)];
如果(!map[num]){
map[num]=i;
结果:推送(num);
}

如果(计数器)性能重要吗?你能改变数组吗?性能重要,我能改变数组这看起来有点像“做我的功课”-问题。另外,如果您尝试了什么,您能告诉我们吗?嗨!这个问题已经解决了。请在发布之前搜索。更多关于搜索的信息。@Sasharievus Mods on通过将线程标记为重复线程来非常积极地阻止线程。有时这种情况发生得太快,以至于我怀疑他们是否能够很好地阅读原始或重复的答案。而我理解避免重复的必要性,这个标记发生得太快了。很酷,但是如果你非常非常不走运的话,它不能永远持续下去?性能是我试图解决的一个问题with@SashaGrievus我已经更新了答案,我已经限制了while循环。它现在不会无限运行。非常感谢。但是让我们这样说吧有些点num一直只是已经选择的数字,这可能会永远持续下去,不是吗?我理解这种情况是有限和荒谬的,但仍然意味着,如果生成大量的“已经选择的num”,这可能需要比所需步骤多得多的步骤,从而导致性能不佳,我认为guess@SashaGrievuswhile循环不会永远消失当我们在每次迭代中递减计数器时。所以当计数器变为零时,我们中断循环。@sasharievus yes correct,以防止您只能在元素重复时从数组中拼接该元素。