190 votes

Comment obtenir un nombre d'éléments aléatoires à partir d'un tableau ?

Je travaille sur "comment accéder à des éléments de manière aléatoire à partir d'un tableau en javascript". J'ai trouvé de nombreux liens à ce sujet. Par exemple : Obtenir un élément aléatoire d'un tableau JavaScript

var item = items[Math.floor(Math.random()*items.length)];

Mais dans ce cas, nous ne pouvons choisir qu'un seul élément du tableau. Si nous voulons plus d'un élément, comment pouvons-nous y parvenir ? Comment obtenir plus d'un élément d'un tableau ?

3voto

0a -archy Points 4224
Array.prototype.getnkill = function() {
    var a = Math.floor(Math.random()*this.length);
    var dead = this[a];
    this.splice(a,1);
    return dead;
}

//.getnkill() removes element in the array 
//so if you like you can keep a copy of the array first:

//var original= items.slice(0); 

var item = items.getnkill();

var anotheritem = items.getnkill();

3voto

Birowsky Points 746

Voici une version dactylographiée. Elle n'échoue pas. Retourne un tableau mélangé si la taille de l'échantillon est plus grande que la longueur du tableau original.

function sampleArr<T>(arr: T[], size: number): T[] {
  const setOfIndexes = new Set<number>();
  while (setOfIndexes.size < size && setOfIndexes.size < arr.length) {
    setOfIndexes.add(randomIntFromInterval(0, arr.length - 1));
  }
  return Array.from(setOfIndexes.values()).map(i => arr[i]);
}

const randomIntFromInterval = (min: number, max: number): number =>
  Math.floor(Math.random() * (max - min + 1) + min);

3voto

haouarin Points 469

Dans cette réponse, je veux partager avec vous le test que j'ai fait pour connaître la meilleure méthode qui donne des chances égales à tous les éléments d'avoir un sous-réseau aléatoire.

Méthode 01

array.sort(() => Math.random() - Math.random()).slice(0, n)

Grâce à cette méthode, certains éléments ont plus de chances que d'autres.

calculateProbability = function(number=0 ,iterations=10000,arraySize=100) { 
let occ = 0 
for (let index = 0; index < iterations; index++) {
   const myArray= Array.from(Array(arraySize).keys()) //=> [0, 1, 2, 3, 4, ... arraySize]

  /** Wrong Method */
    const arr = myArray.sort(function() {
     return val= .5 - Math.random();
      });

  if(arr[0]===number) {
    occ ++
    }

}

console.log("Probability of ",number, " = ",occ*100 /iterations,"%")

}

calculateProbability(0)
calculateProbability(0)
calculateProbability(0)
calculateProbability(50)
calculateProbability(50)
calculateProbability(50)
calculateProbability(25)
calculateProbability(25)
calculateProbability(25)

Méthode 2

Avec cette méthode, les éléments ont la même probabilité :

 const arr = myArray
      .map((a) => ({sort: Math.random(), value: a}))
      .sort((a, b) => a.sort - b.sort)
      .map((a) => a.value)

calculateProbability = function(number=0 ,iterations=10000,arraySize=100) { 
let occ = 0 
for (let index = 0; index < iterations; index++) {
   const myArray= Array.from(Array(arraySize).keys()) //=> [0, 1, 2, 3, 4, ... arraySize]

  /** Correct Method */
  const arr = myArray
  .map((a) => ({sort: Math.random(), value: a}))
  .sort((a, b) => a.sort - b.sort)
  .map((a) => a.value)

  if(arr[0]===number) {
    occ ++
    }

}

console.log("Probability of ",number, " = ",occ*100 /iterations,"%")

}

calculateProbability(0)
calculateProbability(0)
calculateProbability(0)
calculateProbability(50)
calculateProbability(50)
calculateProbability(50)
calculateProbability(25)
calculateProbability(25)
calculateProbability(25)

La bonne réponse est affichée dans le lien suivant : https://stackoverflow.com/a/46545530/3811640

3voto

MAMY Sébastien Points 103

2020
style de programmation fonctionnelle non destructive, travaillant dans un contexte immuable.

const _randomslice = (ar, size) => {
  let new_ar = [...ar];
  new_ar.splice(Math.floor(Math.random()*ar.length),1);
  return ar.length <= (size+1) ? new_ar : _randomslice(new_ar, size);
}

console.log(_randomslice([1,2,3,4,5],2));

1voto

Tibos Points 12774

EDITAR : Cette solution est plus lente que d'autres présentées ici (qui scindent le tableau source) si vous ne voulez obtenir que quelques éléments. La vitesse de cette solution ne dépend que du nombre d'éléments dans le tableau d'origine, alors que la vitesse de la solution d'épissage dépend du nombre d'éléments requis dans le tableau de sortie.

Si vous voulez des éléments aléatoires qui ne se répètent pas, vous pouvez mélanger votre tableau et n'en obtenir que le nombre que vous souhaitez :

function shuffle(array) {
    var counter = array.length, temp, index;

    // While there are elements in the array
    while (counter--) {
        // Pick a random index
        index = (Math.random() * counter) | 0;

        // And swap the last element with it
        temp = array[counter];
        array[counter] = array[index];
        array[index] = temp;
    }

    return array;
}

var arr = [0,1,2,3,4,5,7,8,9];

var randoms = shuffle(arr.slice(0)); // array is cloned so it won't be destroyed
randoms.length = 4; // get 4 random elements

DEMO : http://jsbin.com/UHUHuqi/1/edit

La fonction de lecture aléatoire est reprise ici : https://stackoverflow.com/a/6274398/1669279

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X