Crie uma matriz com valores aleatórios

Respostas:

53

Aqui está uma solução que embaralha uma lista de números únicos (sem repetições, 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);

Se você quiser permitir valores repetidos (o que não é o que o OP queria), procure outro lugar. :)

Phrogz
fonte
4
Essa solução é boa se os números forem únicos, mas isso é uma coisa estatística / probabilística completamente diferente. Espero que isso tenha ficado claro para o OP e não seja relevante no caso deles, mas em alguns casos pode ter um grande impacto sobre a exatidão do programa. (Não estou criticando a resposta, apenas levantando uma bandeira para futuros leitores. Você pode querer mencionar isso.) Veja também: en.wikipedia.org/wiki/Combination (distinção entre "com" ou "sem repetição"
chiccodoro
var random_array = new Array (40) .fill (). map ((a, i) => a = i) .sort (() => Math.random () - 0,5); Eu acho que isso faz o mesmo que acima
Jamie337nichols
Como excluí-lo da geração do número 0?
Gosi
208

A abordagem mais curta (ES6)

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

Aproveitar!

Simonbor
fonte
Você está certo. Excluí meu comentário. Versão corrigida do caminho mais curto atual: [... Array (20)]. Map (() => {return Math.floor (Math.random () * 30)});
jaheraho
7
Se removermos os espaços da abordagem da resposta, são 4 caracteres a menos do que o que você propôs. Claro, se você estiver interessado em jogar golfe, você realmente deixou de fora alguns atalhos fáceis para cortar caracteres: [...Array(40)].map(_=>Math.ceil(Math.random()*40));seriam 11 caracteres a menos que o seu e 7 a menos que o original.
Kyle Baker
(não foi rápido o suficiente para corrigir - precisa ser * 39 para atender aos critérios do OP se usarmos Math.ceil, embora cortemos 0 como uma opção. Se pudermos aceitar 1-40 em vez de 0-39, isso funciona. , reduza um caráter de melhoria para voltar a Math.floor)
Kyle Baker,
excelente !!! obrigado por compartilhar
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
fonte
1
O que há com os argumentos _e i? desnecessário no ES6 a menos que eu esteja enganado.
AfricanMatt de
2
@AfricanMatt, _é o elemento atual e ié o índice atual. Você está certo, eles são desnecessários em ambos os casos. Você pode removê-los se quiser.
Eugene Kulabuhov
1
Não sei onde você acredita que essa versão para ES6 funciona? Array.from funciona ... aqui está um exemplo com seu código ... randomArray = (comprimento: número, máximo: número) => Array.from ({comprimento}) .map (() => Math.floor (Math .random () * max));
Christian Matthew
31

Abordagem ES6 ainda mais curta:

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

Além disso, você pode ter uma função com argumentos:

const randomArray = (length, max) => 
  Array(length).fill().map(() => Math.round(Math.random() * max))
Damjan Pavlica
fonte
1
.fill () requer um parâmetro de valor
Damian Green
4
@DamianGreen - .fill()sem nenhum parâmetro preencherá a matriz com undefined, que é a única coisa necessária aqui para .map()funcionar
vsync
@Damjan existe uma maneira de não repetir números? Adorei essa abordagem
Henrique
@Henrique usando variáveis? 🤔
Sebj,
@Sebj isso é possível? Quer dizer, qualquer abordagem curta como essa e com adereços como comprimento e máximo funcionaria perfeitamente para mim :)
Henrique
31

Mais curto :-)

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

Curt
fonte
18
~~é uma abreviação de Math.floor
Curt
1
isso é ótimo; há amplo apoio para essa ~~abreviação? (editar: ahh, é apenas um operador bit a bit , eu vejo)
Rafe Goldberg
@Curt apenas para números positivos
AJ Uppal
16

Math.random()retornará um número entre 0 e 1 (exclusivo). Então, se você quiser 0-40, pode multiplicá-lo por 40, o maior resultado pode ser pelo que você 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
fonte
1
Para esclarecer: essa é uma letra L, não o número 1, em "l = 40", "i <l" e "Math.random () * l". A fonte torna difícil saber.
Mu Mind
11

.. a matriz que obtenho é muito pouco aleatória. Gera muitos blocos de números sucessivos ...

Seqüências de itens aleatórios geralmente contêm blocos de números sucessivos, veja a Falácia do Jogador . Por exemplo:

.. acabamos de lançar quatro caras consecutivas .. Uma vez que a probabilidade de uma sequência de cinco caras sucessivas é de apenas 1⁄32 .. uma pessoa sujeita à falácia do jogador pode acreditar que esta próxima jogada tinha menos probabilidade de ser cara do que ser caudas. http://en.wikipedia.org/wiki/Gamblers_fallacy

Jared Beck
fonte
+1 exatamente. É necessário decidir se são necessários números reais (estatisticamente) aleatórios ou números que "parecem aleatórios".
chiccodoro
4

Como o intervalo de números é restrito, eu diria que a melhor coisa a fazer é gerar a matriz, preenchê-la com números de zero a 39 (em ordem) e, em seguida, embaralhá-la.

Pontudo
fonte
Aqui está uma visualização dessa técnica (embora essa página use um algoritmo de embaralhamento terrível ).
Phrogz
Eu não sei se ele queria cada número entre, mas completamente aleatório? Se ele está bem com ordem aleatória, valores estáticos, então isso funcionará bem.
Robert,
que pode fazer o trabalho, mas fornecerá resultados ligeiramente diferentes do que se você usasse Math.random()40 vezes, uma vez que forçará cada número aparecendo uma vez e sem repetições.
Mu Mind
4
let randomNumber = Array.from({length: 6}, () => Math.floor(Math.random() * 39));

limitou a matriz a 6 valores para facilitar a visualização.

Rafael
fonte
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 é a maneira tradicional de fazer isso, mas eu apoio @Pointy e @Phrogz se você quiser evitar duplicatas em seu array sem ter que fazer cálculos caros

Ady Ngom
fonte
3

Soluções de linha única peculiares todos os dias.

Os valores em arrays são totalmente aleatórios, portanto, quando você usar esses snippets, será diferente.

Uma matriz (comprimento 10) com caracteres aleatórios em 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']

Uma matriz (comprimento 10) com números inteiros aleatórios de 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]

Uma matriz de datas aleatórias (de 10 anos até agora)

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]

Uma matriz (comprimento 10) strings aleatórias

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

Outras coisas úteis que você pode encontrar aqui https://github.com/setivolkylany/nodejs-utils/blob/master/utils/faker.js

PADYMKO
fonte
1

Usando alguns novos recursos do ES6, isso agora pode ser obtido 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);

Observe que esta solução só funcionará em navegadores modernos que suportam esses recursos ES6: funções de seta e Array.from ().

Lachlan Hunt
fonte
1

Consulte abaixo: -

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

da 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
fonte
0

Eu precisava de algo um pouco diferente do que essas soluções ofereciam, pois precisava criar uma matriz com vários números aleatórios distintos mantidos em um intervalo especificado. Abaixo está minha solução.

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

Eu teria preferido não criar um loop que pudesse terminar com muitas chamadas desnecessárias (se sua contagem e intervalo forem altos e próximos ao mesmo número), mas este é o melhor que eu poderia fazer.

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

Eu acho que este método vai resolver o problema com as probabilidades, apenas limitadas pelo gerador de números aleatórios.

Peter Pshenichny
fonte
0

Se você precisar dele com valores únicos aleatórios de 0 ... intervalo de comprimento:

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]
gerador ideal
fonte
0

Tenho certeza de que esta é a maneira mais curta de criar seu array aleatório sem nenhuma repetição

var random_array = new Array(40).fill().map((a, i) => a = i).sort(() => Math.random() - 0.5);
Jamie337nichols
fonte
"com certeza", que tal usar a keysfunção Array.from(Array(40).keys()).sort(_ => Math.random() - .5):? Você pode até ficar louco e usar o operador de propagação! Mas isso é muito emocionante para mim agora.
Yeti
0

Um pouco tarde para a festa, mas eu uso randojs.com para aleatoriedade porque torna esse tipo de coisa super fácil. Você pode obter uma matriz aleatória de números de 0 a 39, assim:

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

Sem complicações com a logística de tudo - além de ser super legível e fácil de entender :)

Aaron Plocharczyk
fonte
0

Geradores

Uma matriz de comprimento 40 de 40 valores possíveis aleatórios (0 - 39) sem valores repetidos é melhor embaralhar como explicam @Phrogz e @Jared Beck. Outra abordagem, apenas para os registros, poderia ser o uso de geradores. Mas essa abordagem carece de desempenho em comparação com outras soluções propostas .

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