Crea una matriz con valores aleatorios

Respuestas:

53

Aquí hay una solución que mezcla una lista de números únicos (sin repeticiones, nunca).

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);

Si desea permitir valores repetidos (que no es lo que quería el OP), busque en otra parte. :)

Phrogz
fuente
4
Esta solución es buena si los números deben ser únicos, pero esto es algo estadístico / probabilístico completamente diferente. Espero que esto haya quedado claro para el PO y no sea relevante en su caso, pero en ciertos casos puede tener un gran impacto en la corrección del programa. (No estoy criticando la respuesta, solo estoy levantando una bandera para los futuros lectores. Es posible que desee mencionar eso). Vea también: en.wikipedia.org/wiki/Combination (distinción entre "con" o "sin repetición"
chiccodoro
var matriz_aleatoria = nueva matriz (40) .fill (). map ((a, i) => a = i) .sort (() => Math.random () - 0.5); Creo que esto hace lo mismo que el anterior
Jamie337nichols
¿Cómo excluirlo de generar el número 0?
Gosi
208

El enfoque más corto (ES6)

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

¡Disfrutar!

Simonbor
fuente
Tienes razón. Borré mi comentario. Versión corregida del camino más corto actual: [... Array (20)]. Map (() => {return Math.floor (Math.random () * 30)});
jaheraho
7
Si quitamos los espacios del enfoque de la respuesta, son 4 caracteres menos que el que propuso. Por supuesto, si está interesado en jugar al golf, en realidad dejó de lado algunos atajos fáciles de cortar de personajes: [...Array(40)].map(_=>Math.ceil(Math.random()*40));serían 11 caracteres menos que los suyos y 7 menos que el original.
Kyle Baker
(no fue lo suficientemente rápido para corregir; debe ser * 39 para cumplir con los criterios del OP si lo usamos Math.ceil, aunque cortamos 0 como una opción. Si podemos aceptar 1-40 en lugar de 0-39, esto funciona. De lo contrario , reducir un carácter de mejora para volver a Math.floor)
Kyle Baker
excelente !!! gracias por compartir
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));
Eugene Kulabuhov
fuente
1
¿Qué pasa con los argumentos _y i? innecesario en ES6 a menos que me equivoque.
AfricanMatt
2
@AfricanMatt, _es el elemento actual y ies el índice actual. Tienes razón, son innecesarios en ambos casos. Puede eliminarlos si lo desea.
Eugene Kulabuhov
1
No sé dónde cree que funciona esa versión para ES6. Array.from works ... aquí hay un ejemplo con su código ... randomArray = (length: number, max: number) => Array.from ({length}) .map (() => Math.floor (Math .random () * max));
Christian Matthew
31

Enfoque ES6 aún más corto:

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

Además, podría tener una función con argumentos:

const randomArray = (length, max) => 
  Array(length).fill().map(() => Math.round(Math.random() * max))
Damjan Pavlica
fuente
1
.fill () requiere un parámetro de valor
Damian Green
4
@DamianGreen: .fill()sin ningún parámetro, se llenará la matriz undefined, que es lo único que se necesita aquí para .map()que funcione
vsync
@Damjan, ¿hay alguna manera de no repetir números? Me encantó este enfoque
Henrique
@Henrique usando variables? 🤔
Sebj
@Sebj ¿es eso posible? Quiero decir, cualquier enfoque corto como este y con accesorios como length y max funcionaría perfectamente para mí :)
Henrique
31

Más corto :-)

[...Array(40)].map(e=>~~(Math.random()*40))

Brusco
fuente
18
~~es la abreviatura de Math.floor
Curt
1
esto es genial; ¿Existe un apoyo generalizado para esa ~~taquigrafía? (editar: ahh, es solo un operador bit a bit , ya veo)
Rafe Goldberg
@Curt solo para números positivos
AJ Uppal
16

Math.random()devolverá un número entre 0 y 1 (exclusivo). Entonces, si quiere 0-40, puede multiplicarlo por 40, el resultado más alto que puede ser es por lo que está multiplicando.

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/

Robert
fuente
1
Para aclarar: esa es una letra L, no el número 1, en "l = 40", "i <l" y "Math.random () * l". La fuente hace que sea difícil saberlo.
Mu Mind
11

.. la matriz que obtengo es muy poco aleatoria. Genera muchos bloques de números sucesivos ...

Las secuencias de elementos aleatorios a menudo contienen bloques de números sucesivos, consulte la falacia del jugador . Por ejemplo:

.. acabamos de lanzar cuatro caras seguidas .. Dado que la probabilidad de una serie de cinco caras sucesivas es sólo 1⁄32 .. una persona sujeta a la falacia del jugador podría creer que este próximo lanzamiento tiene menos probabilidades de ser caras que ser colas. http://en.wikipedia.org/wiki/Gamblers_fallacy

Jared Beck
fuente
+1 exactamente. Es necesario decidir si se necesitan números aleatorios reales (estadísticamente) o números que "parecen aleatorios".
chiccodoro
5
let randomNumber = Array.from({length: 6}, () => Math.floor(Math.random() * 39));

limitó la matriz a 6 valores para que sea fácil de ver.

Rafael
fuente
4

Dado que el rango de números está restringido, yo diría que lo mejor que se puede hacer es generar la matriz, llenarla con números del cero al 39 (en orden) y luego mezclarla.

Puntiagudo
fuente
No sé si quería todos los números intermedios, ¿pero completamente al azar? Si está bien con el orden aleatorio, los valores estáticos, entonces esto funcionará bien.
Robert
que puede hacer el trabajo, pero dará resultados ligeramente diferentes que si lo usara Math.random()40 veces, ya que hará cumplir cada número que aparece una vez y no se repite.
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));
}

Esta es la forma tradicional de hacerlo, pero segundo @Pointy y @Phrogz si desea evitar duplicados en su matriz sin tener que hacer cálculos costosos

Ady Ngom
fuente
3

Quirk soluciones de una sola línea todos los días.

Los valores en las matrices son totalmente aleatorios, por lo que cuando utilice estos fragmentos, será diferente.

Una matriz (longitud 10) con caracteres aleatorios en minúsculas

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']

Una matriz (longitud 10) con números enteros aleatorios del 0 al 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]

Una matriz de fechas aleatorias (desde hace 10 años hasta ahora)

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, 2014-08-06T21: 00: 00.000Z]

Una matriz (longitud 10) cadenas aleatorias

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']

Otras cosas útiles que puede encontrar aquí https://github.com/setivolkylany/nodejs-utils/blob/master/utils/faker.js

PADYMKO
fuente
1

Usando algunas características nuevas de ES6, esto ahora se puede lograr usando:

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);

Tenga en cuenta que esta solución solo funcionará en navegadores modernos que admitan estas características de ES6: funciones de flecha y Array.from ().

Caza de Lachlan
fuente
1

Consulte a continuación: -

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

de la página sugerida por @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 } );
Luis Siquot
fuente
0

Necesitaba algo un poco diferente a lo que ofrecían estas soluciones, ya que necesitaba crear una matriz con una cantidad de números aleatorios distintos mantenidos en un rango específico. A continuación se muestra mi solución.

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; 
}

Hubiera preferido no crear un bucle que tuviera la posibilidad de terminar con muchas llamadas innecesarias (si su recuento y rango son altos y están cerca del mismo número), pero esto es lo mejor que pude encontrar.

Joe
fuente
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
}

Supongo que este método resolverá el problema con las probabilidades, solo limitado por el generador de números aleatorios.

Peter Pshenichny
fuente
0

Si lo necesita con valores únicos aleatorios de 0 ... rango de longitud:

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]
generador de vida ideal
fuente
0

Estoy bastante seguro de que esta es la forma más corta de crear su matriz aleatoria sin repeticiones

var random_array = new Array(40).fill().map((a, i) => a = i).sort(() => Math.random() - 0.5);
Jamie337nichols
fuente
"bastante seguro", ¿qué tal si usas la keysfunción Array.from(Array(40).keys()).sort(_ => Math.random() - .5):? ¡Incluso podría volverse loco y usar el operador de propagación! Pero eso es demasiado emocionante para mí en este momento.
Yeti
0

Un poco tarde para la fiesta, pero uso randojs.com para aleatoriedad porque hace que este tipo de cosas sea muy fácil. Puede obtener una matriz aleatoria de números del 0 al 39 de la siguiente manera:

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

Sin problemas con la logística de todo, además es súper legible y fácil de entender :)

Aaron Plocharczyk
fuente
0

Generadores

Una matriz de longitud 40 de 40 valores posibles aleatorios (0 - 39) sin valores repetidos es mejor para mezclarla como explican @Phrogz y @Jared Beck. Otro enfoque, solo para los registros, podría ser el uso de generadores. Pero este enfoque carece de rendimiento en comparación con otras soluciones propuestas .

function* generateRandomIterable(n, range) {
  for (let i = 0; i < n; i++) {
    yield ~~(Math.random() * range);
  }
}
const randomArr = [...generateRandomIterable(40,40)];
brbn
fuente