Randomizza o mescola un array in JavaScript

Moataz Farid 12 ottobre 2023
  1. Mescola un array in base al motore JavaScript
  2. Misura la casualità del nostro semplice algoritmo
  3. Mescola un array utilizzando l’algoritmo di riproduzione casuale Fisher-Yates
  4. Mescola un array con la libreria Underscore.js o Lo-Dash
Randomizza o mescola un array in JavaScript

In questo tutorial impareremo come mescolare o randomizzare un array in JavaScript; ci sono molti modi per mescolare un array in JavaScript, sia implementando algoritmi di mescolamento o utilizzando funzioni di mescolamento già esistenti in alcune librerie.

Mescolare un array significa disporre il suo elemento in modo casuale, quindi dipende principalmente da come riordini o ordina l’array con un certo grado di casualità.

Andiamo avanti e scopriamo diversi modi per randomizzare o mescolare un array.

Mescola un array in base al motore JavaScript

Cominciamo con l’implementazione di un semplice algoritmo di mescolamento degli array ordinando l’array usando array.sort() ma usando una certa casualità generata dall’equazione Math.random() - 0.5 e -0.5 assicura che ogni volta che chiamiamo il algoritmo, il valore casuale può essere positivo o negativo.

Implementiamo questo semplice algoritmo con la potenza del motore JavaScript e stampiamo l’Array mescolato sulla console usando Console.log():

function shuffleArray(inputArray) {
  inputArray.sort(() => Math.random() - 0.5);
}

var demoArray = [1, 3, 5];
shuffleArray(demoArray);
console.log(demoArray);

Produzione:

[1, 5, 3]

Misura la casualità del nostro semplice algoritmo

La probabilità delle permutazioni di quell’array può essere calcolata per verificare quanto sia eccellente e casuale il nostro algoritmo che abbiamo implementato.

Vediamo come possiamo misurare la sua casualità.

  1. Creare un dizionario che conterà l’aspetto per tutte le permutazioni.
  2. Creare un bucle che verrà eseguito 1000000 volte e ogni volta aumenterà il conteggio della permutazione formata
  3. Stampare i conteggi di tutte le possibili permutazioni e osservare le probabilità tra di loro.

Questo semplice algoritmo di misurazione può essere implementato come segue:

function shuffleArray(inputArray) {
  inputArray.sort(() => Math.random() - 0.5);
}

// counts of the appearances for all possible permutations
var countDic = {
  '153': 0,
  '135': 0,
  '315': 0,
  '351': 0,
  '531': 0,
  '513': 0,
};

// Creating the loop
for (var i = 0; i < 1000000; i++) {
  var arr = [1, 5, 3];
  shuffleArray(arr);
  countDic[arr.join('')]++;
}

// Print the counts of all possible permutations
for (var key in countDic) {
  console.log(`${key}: ${countDic[key]}`);
}

Produzione:

135: 62256
153: 375832
315: 62976
351: 311865
513: 124518
531: 62553

Dall’output di cui sopra, possiamo vedere chiaramente il bias come 135, 315 e 531 appaiono molto meno di altri e quindi conteggi simili tra loro.

Mescola un array utilizzando l’algoritmo di riproduzione casuale Fisher-Yates

Questo semplice algoritmo basato sul motore JavaScript non è affidabile nella sezione precedente, ma un ottimo algoritmo chiamato Fisher-Yates è migliore per quanto riguarda la sua efficienza e affidabilità.

L’idea alla base dell’algoritmo Fisher-Yates è di camminare sull’array in ordine inverso e scambiare ogni elemento con uno casuale prima di esso. Fisher-Yates è un algoritmo semplice ma molto efficiente e veloce.

Implementiamo l’algoritmo Fisher-Yates:

function fisherYatesShuffle(arr) {
  for (var i = arr.length - 1; i > 0; i--) {
    var j = Math.floor(Math.random() * (i + 1));  // random index
    [arr[i], arr[j]] = [arr[j], arr[i]];          // swap
  }
}

var tmpArray = [1, 3, 5];
fisherYatesShuffle(tmpArray);
console.log(tmpArray);

Quindi spiegiamolo passo dopo passo:

  1. for(var i =array.length-1 ; i>0 ;i--) un bucle for che camminerà sull’array in ordine inverso.
  2. Math.floor( Math.random() * (i + 1) ) Generazione di un indice casuale compreso tra 0 e i.
  3. [arr[i],arr[j]]=[arr[j],arr[i]] sta scambiando gli elementi arr[i] e arr[j] l’uno con l’altro usando il Sintassi di assegnazione destrutturante.

Produzione:

(3) [3, 1, 5]

Ora proviamo Fisher-Yates come abbiamo fatto prima:

// counts of the appearances for all possible permutations
var countDic = {
  '153': 0,
  '135': 0,
  '315': 0,
  '351': 0,
  '531': 0,
  '513': 0,
};

// Creating the loop
for (var i = 0; i < 1000000; i++) {
  var arr = [1, 5, 3];
  fisherYatesShuffle(arr);
  countDic[arr.join('')]++;
}

// Print the counts of all possible permutations
for (var key in countDic) {
  console.log(`${key}: ${countDic[key]}`);
}

Produzione:

135: 166734
153: 166578
315: 166908
351: 166832
513: 166535
531: 166413

Dall’output di cui sopra, puoi vedere la grande differenza tra l’algoritmo Fisher-Yates e il semplice algoritmo che abbiamo implementato prima e quanto sia affidabile l’algoritmo Fisher-Yates.

Mescola un array con la libreria Underscore.js o Lo-Dash

La famosa libreria Underscore.js fornisce anche una funzione shuffle che può randomizzare direttamente un array senza la necessità di scrivere l’implementazione di alcun algoritmo.

Vediamo il seguente esempio di utilizzo del metodo _.shuffle().

Innanzitutto, dobbiamo importare la libreria utilizzando Cloudflare CDN all’interno del modello HTML,

<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js"></script>

Quindi usiamo il metodo _.shuffle() come:

var tmpUnderscoreArray = [1, 3, 5];
resultArray = _.shuffle(tmpUnderscoreArray);
console.log(resultArray);

Produzione:

(3) [1, 5, 3]

Articolo correlato - JavaScript Array