Crea un array con valori casuali


Risposte:


53

Ecco una soluzione che mescola un elenco di numeri univoci (nessuna ripetizione, mai).

for (var a=[],i=0;i<40;++i) a[i]=i;

// http://stackoverflow.com/questions/962802#962890
function shuffle(array) {
  var tmp, current, top = array.length;
  if(top) while(--top) {
    current = Math.floor(Math.random() * (top + 1));
    tmp = array[current];
    array[current] = array[top];
    array[top] = tmp;
  }
  return array;
}

a = shuffle(a);

Se vuoi consentire valori ripetuti (che non è quello che voleva l'OP), cerca altrove. :)


4
Questa soluzione è buona se i numeri devono essere univoci, ma questa è una cosa statistica / probabilistica completamente diversa. Spero che questo fosse chiaro al PO e non fosse rilevante nel loro caso, ma in alcuni casi può avere un grande impatto sulla correttezza del programma. (Non sto criticando la risposta, sto solo alzando una bandiera per i lettori futuri. Potresti menzionarlo.) Vedi anche: en.wikipedia.org/wiki/Combination (distinzione tra "con" o "senza ripetizione"
chiccodoro

var random_array = new Array (40) .fill (). map ((a, i) => a = i) .sort (() => Math.random () - 0.5); Penso che questo faccia lo stesso come sopra
Jamie337nichols

Come escluderlo dalla generazione del numero 0?
Gosi

208

L'approccio più breve (ES6)

// randomly generated N = 40 length array 0 <= A[N] <= 39
Array.from({length: 40}, () => Math.floor(Math.random() * 40));

Godere!


Hai ragione. Ho cancellato il mio commento. Versione corretta dell'attuale via più breve: [... Array (20)]. Map (() => {return Math.floor (Math.random () * 30)});
jaheraho

7
Se rimuoviamo gli spazi dall'approccio della risposta, sono 4 caratteri in meno rispetto a quello che hai proposto. Ovviamente, se sei interessato a giocare a golf, in realtà hai tralasciato alcune facili scorciatoie per tagliare i personaggi: [...Array(40)].map(_=>Math.ceil(Math.random()*40));sarebbero 11 caratteri in meno del tuo e 7 meno dell'originale.
Kyle Baker

(non è stato abbastanza veloce da correggere - deve essere * 39 per soddisfare i criteri dell'OP se lo usiamo Math.ceil, anche se abbiamo eliminato 0 come opzione. Se possiamo accettare 1-40 invece di 0-39, funziona. Altrimenti , ridurre un carattere di miglioramento per tornare a Math.floor)
Kyle Baker

eccellente !!! grazie per la condivisione
Adriel Werlich

43

ES5:

function randomArray(length, max) {
    return Array.apply(null, Array(length)).map(function() {
        return Math.round(Math.random() * max);
    });
}

ES6:

randomArray = (length, max) => [...new Array(length)]
    .map(() => Math.round(Math.random() * max));

1
Che succede con gli argomenti _e i? non necessario in ES6 a meno che non mi sbagli.
Africano,

2
@AfricanMatt, _è l'elemento corrente ed iè l'indice corrente. Hai ragione, non sono necessari in entrambi i casi. Puoi rimuoverli se lo desideri.
Eugene Kulabuhov

1
Non so dove credi che la versione per ES6 funzioni? Array.from funziona ... ecco un esempio con il tuo codice ... randomArray = (length: number, max: number) => Array.from ({length}) .map (() => Math.floor (Math .random () * max));
Christian Matthew

31

Approccio ES6 ancora più breve:

Array(40).fill().map(() => Math.round(Math.random() * 40))

Inoltre, potresti avere una funzione con argomenti:

const randomArray = (length, max) => 
  Array(length).fill().map(() => Math.round(Math.random() * max))

1
.fill () richiede un parametro valore
Damian Green

4
@DamianGreen - .fill()senza alcun parametro riempirà l'array undefined, che è l'unica cosa necessaria qui per .map()funzionare
vsync

@ Damjan c'è un modo per non ripetere i numeri? Mi è piaciuto molto questo approccio
Henrique

@Henrique usando le variabili? 🤔
Sebj

@Sebj è possibile? Voglio dire, qualsiasi approccio breve come questo e con oggetti di scena come lunghezza e max funzionerebbe perfettamente per me :)
Henrique


16

Math.random()restituirà un numero compreso tra 0 e 1 (esclusivo). Quindi, se vuoi 0-40, puoi moltiplicarlo per 40, il più alto che il risultato può mai essere è quello per cui stai moltiplicando.

var arr = [];
for (var i=0, t=40; i<t; i++) {
    arr.push(Math.round(Math.random() * t))
}
document.write(arr);

http://jsfiddle.net/robert/tUW89/


1
Per chiarire: è una lettera L, non il numero 1, in "l = 40", "i <l" e "Math.random () * l". Il carattere lo rende difficile da dire.
Mu Mind

11

.. l'array che ottengo è molto poco casuale. Genera molti blocchi di numeri successivi ...

Le sequenze di oggetti casuali spesso contengono blocchi di numeri successivi, vedere l' errore del giocatore . Per esempio:

.. abbiamo appena lanciato quattro teste di fila .. Poiché la probabilità di una serie di cinque teste consecutive è solo 1⁄32 .. una persona soggetta all'errore del giocatore potrebbe credere che il prossimo lancio fosse meno probabile che fosse testa di essere code. http://en.wikipedia.org/wiki/Gamblers_fallacy


+1 esattamente. È necessario decidere se sono necessari numeri casuali reali (statisticamente) o numeri che "sembrano casuali".
chiccodoro

5
let randomNumber = Array.from({length: 6}, () => Math.floor(Math.random() * 39));

limitato l'array a 6 valori per renderlo facile da vedere.


4

Poiché l'intervallo di numeri è limitato, direi che la cosa migliore da fare è generare l'array, riempirlo con numeri da zero a 39 (in ordine), quindi mescolarlo.



Non so se voleva ogni numero compreso tra, ma piuttosto completamente casuale? Se sta bene con l'ordine casuale, i valori statici allora funzionerà bene.
Robert

che potrebbe fare il lavoro, ma darà risultati leggermente diversi rispetto a se lo usassi Math.random()40 volte, poiché imporrà che ogni numero appaia una volta e nessuna ripetizione.
Mu Mind

3
var myArray = [];
var arrayMax = 40;
var limit = arrayMax + 1;
for (var i = 0; i < arrayMax; i++) {
  myArray.push(Math.floor(Math.random()*limit));
}

Questo sopra è il modo tradizionale di farlo, ma secondo @Pointy e @Phrogz se vuoi evitare duplicati nel tuo array senza dover eseguire calcoli costosi


3

Quirk soluzioni single-line ogni giorno.

I valori negli array sono totalmente casuali, quindi quando utilizzerai questi frammenti, sarà diverso.

Un array (lunghezza 10) con caratteri casuali in minuscolo

Array.apply(null, Array(10)).map(function() { return String.fromCharCode(Math.floor(Math.random() * (123 - 97) + 97)); })

["k", "a", "x", "y", "n", "w", "m", "q", "b", "j"]

Un array (lunghezza 10) con numeri interi casuali da 0 a 99

Array.apply(null, Array(10)).map(function() { return Math.floor(Math.random() * 100 % 100); })

[86, 77, 83, 27, 79, 96, 67, 75, 52, 21]

Un array di date casuali (da 10 anni ad oggi)

Array.apply(null, Array(10)).map(function() { return new Date((new Date()).getFullYear() - Math.floor(Math.random() * 10), Math.floor(Math.random() * 12), Math.floor(Math.random() * 29) )})

[2008-08-22T21: 00: 00.000Z, 2007-07-17T21: 00: 00.000Z,
2015-05-05T21: 00: 00.000Z, 2011-06-14T21: 00: 00.000Z,
2009-07-23T21 : 00: 00.000Z, 2009-11-13T22: 00: 00.000Z,
2010-05-09T21: 00: 00.000Z, 2008-01-05T22: 00: 00.000Z,
2016-05-06T21: 00: 00.000Z, 06-08-2014T21: 00: 00.000Z]

Un array (lunghezza 10) stringhe casuali

Array.apply(null, Array(10)).map(function() { return Array.apply(null, Array(Math.floor(Math.random() * 10  + 3))).map(function() { return String.fromCharCode(Math.floor(Math.random() * (123 - 97) + 97)); }).join('') });

["cubjjhaph", "bmwy", "alhobd", "ceud", "tnyullyn", "vpkdflarhnf", "hvg", "arazuln", "jzz", "cyx"]

Altre cose utili che potresti trovare qui https://github.com/setivolkylany/nodejs-utils/blob/master/utils/faker.js


1

Utilizzando alcune nuove funzionalità di ES6, ora è possibile ottenere questo risultato utilizzando:

function getRandomInt(min, max) {
    "use strict";
    if (max < min) {
        // Swap min and max
        [min, max] = [min, max];
    }

    // Generate random number n, where min <= n <= max
    let range = max - min + 1;
    return Math.floor(Math.random() * range) + min;
}

let values = Array.from({length: 40}, () => getRandomInt(0, 40));

console.log(values);

Si noti che questa soluzione funzionerà solo nei browser moderni che supportano queste funzionalità ES6: funzioni freccia e Array.from ().


1

Fare riferimento di seguito: -

let arr = Array.apply(null, {length: 1000}).map(Function.call, Math.random)
/* will create array with 1000 elements */

0

dalla pagina suggerita da @Phrogz

for (var i=0,nums=[];i<49;i++) nums[i]={ n:i, rand:Math.random() };
nums.sort( function(a,b){ a=a.rand; b=b.rand; return a<b?-1:a>b?1:0 } );

0

Avevo bisogno di qualcosa di un po 'diverso da quello che fornivano queste soluzioni, in quanto avevo bisogno di creare un array con un numero di numeri casuali distinti contenuti in un intervallo specificato. Di seguito è la mia soluzione.

function getDistinctRandomIntForArray(array, range){
   var n = Math.floor((Math.random() * range));
   if(array.indexOf(n) == -1){        
    return n; 
   } else {
    return getDistinctRandomIntForArray(array, range); 
   }
}

function generateArrayOfRandomInts(count, range) {
   var array = []; 
   for (i=0; i<count; ++i){
    array[i] = getDistinctRandomIntForArray(array, range);
   };
   return array; 
}

Avrei preferito non creare un loop che ha la possibilità di finire con molte chiamate non necessarie (se il tuo conteggio e la portata sono alti e sono vicini allo stesso numero) ma questo è il meglio che potrei trovare.


0
function shuffle(maxElements) {
    //create ordered array : 0,1,2,3..maxElements
    for (var temArr = [], i = 0; i < maxElements; i++) {
        temArr[i] = i;
    }

    for (var finalArr = [maxElements], i = 0; i < maxElements; i++) {
        //remove rundom element form the temArr and push it into finalArrr
        finalArr[i] = temArr.splice(Math.floor(Math.random() * (maxElements - i)), 1)[0];
    }

    return finalArr
}

Immagino che questo metodo risolverà il problema con le probabilità, limitate solo dal generatore di numeri casuali.


0

Se ne hai bisogno con valori univoci casuali da 0 ... intervallo di lunghezza:

const randomRange = length => {
  const results = []
  const possibleValues = Array.from({ length }, (value, i) => i)

  for (let i = 0; i < length; i += 1) {
    const possibleValuesRange = length - (length - possibleValues.length)
    const randomNumber = Math.floor(Math.random() * possibleValuesRange)
    const normalizedRandomNumber = randomNumber !== possibleValuesRange ? randomNumber : possibleValuesRange

    const [nextNumber] = possibleValues.splice(normalizedRandomNumber, 1)

    results.push(nextNumber)
  }

  return results
}

randomRange(5) // [3, 0, 1, 4, 2]

0

Sono abbastanza sicuro che questo sia il modo più breve per creare il tuo array casuale senza ripetizioni

var random_array = new Array(40).fill().map((a, i) => a = i).sort(() => Math.random() - 0.5);

"abbastanza sicuro", che ne dici di usare la keysfunzione Array.from(Array(40).keys()).sort(_ => Math.random() - .5):? Potresti persino impazzire e utilizzare l'operatore di diffusione! Ma è troppo eccitante per me adesso.
Yeti

0

Un po 'tardi per la festa, ma uso randojs.com per casualità perché rende cose come queste super facili. Puoi ottenere un array di numeri mescolato casualmente da 0 a 39 proprio in questo modo:

console.log(randoSequence(40));
<script src="https://randojs.com/1.0.0.js"></script>

Nessun problema con la logistica di tutto questo, inoltre è super leggibile e facile da capire :)


0

Generatori

Un array di lunghezza 40 di 40 possibili valori casuali (0-39) senza valori ripetuti è meglio mescolarlo come spiegano @Phrogz e @Jared Beck. Un altro approccio, solo per i record, potrebbe essere l'utilizzo di generatori. Ma questo approccio manca di prestazioni rispetto ad altre soluzioni proposte .

function* generateRandomIterable(n, range) {
  for (let i = 0; i < n; i++) {
    yield ~~(Math.random() * range);
  }
}
const randomArr = [...generateRandomIterable(40,40)];
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.