Utwórz tablicę z losowymi wartościami


Odpowiedzi:


54

Oto rozwiązanie, które tasuje listę unikatowych liczb (bez powtórzeń, nigdy).

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

Jeśli chcesz zezwolić na powtarzanie wartości (co nie jest tym, czego chciał PO), poszukaj gdzie indziej. :)


4
To rozwiązanie jest dobre, jeśli liczby powinny być unikalne, ale to zupełnie inna sprawa statystyczna / probabilistyczna. Mam nadzieję, że było to jasne dla PO i nie miało to znaczenia w ich przypadku, ale w niektórych przypadkach może mieć duży wpływ na poprawność programu. (Nie krytykuję odpowiedzi, po prostu podnoszę flagę dla przyszłych czytelników. Możesz o tym wspomnieć.) Zobacz też: en.wikipedia.org/wiki/Combination (rozróżnienie między „z” a „bez powtórzeń”
chiccodoro

var random_array = new Array (40) .fill (). map ((a, i) => a = i) .sort (() => Math.random () - 0,5); Myślę, że robi to samo co powyżej
Jamie337nichols

Jak wykluczyć go z generowania liczby 0?
Gosi

209

Najkrótsze podejście (ES6)

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

Cieszyć się!


Masz rację. Usunąłem mój komentarz. Poprawiona wersja aktualnej najkrótszej drogi: [... Array (20)]. Map (() => {return Math.floor (Math.random () * 30)});
jaheraho

7
Jeśli usuniemy spacje z podejścia do odpowiedzi, będzie to o 4 znaki mniej niż zaproponowano. Oczywiście, jeśli jesteś zainteresowany grą w golfa, tak naprawdę pominąłeś kilka łatwych skrótów do cięcia znaków: [...Array(40)].map(_=>Math.ceil(Math.random()*40));byłoby 11 znaków mniej niż twoje i 7 mniej niż oryginał.
Kyle Baker

(nie było wystarczająco szybkie, aby poprawić - musi być * 39, aby spełnić kryteria PO, jeśli używamy Math.ceil, chociaż wycinamy 0 jako opcję. Jeśli możemy zaakceptować 1-40 zamiast 0-39, to działa. W przeciwnym razie , zmniejsz charakter poprawy, aby wrócić do Math.floor)
Kyle Baker

45

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
O co chodzi z argumentami _i i? niepotrzebne w ES6, chyba że się mylę.
AfricanMatt

2
@AfricanMatt _jest bieżącym elementem i ijest bieżącym indeksem. Masz rację, w obu przypadkach są niepotrzebne. Możesz je usunąć, jeśli chcesz.
Eugene Kulabuhov

1
Nie wiem, gdzie według Ciebie działa wersja na ES6? Array.from działa ... oto przykład z twoim kodem ... randomArray = (length: number, max: number) => Array.from ({length}) .map (() => Math.floor (Math . losowo () * max));
Christian Matthew

32

Jeszcze krótsze podejście ES6:

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

Możesz także mieć funkcję z argumentami:

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

1
.fill () wymaga parametru wartości
Damian Green

4
@DamianGreen - .fill()bez żadnego parametru zapełni tablicę undefined, co jest jedyną potrzebną rzeczą tutaj .map()do pracy
vsync

@Damjan czy jest sposób, aby nie powtarzać liczb? Podobało mi się to podejście
Henrique

@Henrique używa zmiennych? 🤔
Sebj

@Sebj czy to możliwe? Chodzi mi o to, że każde podejście takie krótkie i z rekwizytami jako długością i maksimum byłoby dla mnie idealne :)
Henrique


16

Math.random()zwróci liczbę od 0 do 1 (wyłącznie). Tak więc, jeśli chcesz, aby 0-40, możesz pomnożyć to przez 40, najwyższy wynik, jaki kiedykolwiek uzyskasz, to mnożenie przez.

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
Dla wyjaśnienia: to litera L, a nie cyfra 1, w „l = 40”, „i <l” i „Math.random () * l”. Czcionka sprawia, że ​​trudno powiedzieć.
Mu Mind

11

.. otrzymana tablica jest bardzo mało zrandomizowana. Generuje bardzo dużo bloków kolejnych liczb ...

Sekwencje losowych przedmiotów często zawierają bloki kolejnych liczb, zobacz błąd Hazardzisty . Na przykład:

.. właśnie rzuciliśmy cztery reszki z rzędu .. Ponieważ prawdopodobieństwo serii pięciu kolejnych reszek wynosi tylko 1⁄32 .. osoba podlegająca błędowi hazardzisty może sądzić, że ten następny rzut był mniej prawdopodobny niż być ogonami. http://en.wikipedia.org/wiki/Gamblers_fallacy


+1 dokładnie. Trzeba zdecydować, czy potrzebne są liczby rzeczywiste (statystycznie) losowe, czy liczby „wyglądające na losowe”.
chiccodoro,

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

ograniczył tablicę do 6 wartości, aby była łatwa do zobaczenia.


4

Ponieważ zakres liczb jest ograniczony, powiedziałbym, że najlepszą rzeczą do zrobienia jest wygenerowanie tablicy, wypełnienie jej liczbami od 0 do 39 (w kolejności), a następnie przetasowanie.



Nie wiem, czy chciał każdą liczbę pomiędzy, ale raczej całkowicie przypadkową? Jeśli pasuje mu losowa kolejność, wartości statyczne, to będzie działać dobrze.
Robert

co może załatwić Math.random()sprawę , ale da nieco inne wyniki niż w przypadku użycia 40 razy, ponieważ wymusi to, że każda liczba pojawi się raz i nie będzie się powtarzać.
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));
}

Powyżej jest to tradycyjny sposób, ale ja drugi raz @Pointy i @Phrogz, jeśli chcesz uniknąć duplikatów w swojej tablicy bez konieczności wykonywania kosztownych obliczeń


3

Dziwaczne rozwiązania jednoliniowe na co dzień.

Wartości w tablicach są całkowicie losowe, więc kiedy będziesz używać tych fragmentów, będzie inaczej.

Tablica (długość 10) z losowymi znakami małymi literami

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

Tablica (długość 10) z losowymi liczbami całkowitymi od 0 do 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]

Tablica losowych dat (od 10 lat wstecz do teraz)

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]

Tablica (długość 10) losowych ciągów

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

Inne przydatne rzeczy, które możesz znaleźć tutaj https://github.com/setivolkylany/nodejs-utils/blob/master/utils/faker.js


1

Korzystając z kilku nowych funkcji ES6, można to teraz osiągnąć za pomocą:

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

Zwróć uwagę, że to rozwiązanie będzie działać tylko w nowoczesnych przeglądarkach obsługujących te funkcje ES6: funkcje strzałek i Array.from ().


1

Zobacz poniżej: -

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

0

ze strony sugerowanej przez @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

Potrzebowałem czegoś nieco innego niż to, co dały te rozwiązania, ponieważ musiałem utworzyć tablicę z wieloma różnymi liczbami losowymi przechowywanymi w określonym zakresie. Poniżej moje rozwiązanie.

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

Wolałbym nie tworzyć pętli, która może zakończyć się dużą liczbą niepotrzebnych połączeń (jeśli liczba i zasięg są wysokie i są zbliżone do tej samej liczby), ale to najlepsze, co mogłem wymyślić.


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
}

Myślę, że ta metoda rozwiąże problem z prawdopodobieństwami ograniczonymi tylko przez generator liczb losowych.


0

Jeśli potrzebujesz go z losowymi unikalnymi wartościami z 0 ... zakresu długości:

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

Jestem prawie pewien, że jest to najkrótszy sposób na utworzenie losowej tablicy bez żadnych powtórzeń

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

„całkiem pewnie”, a co powiesz na użycie keysfunkcji Array.from(Array(40).keys()).sort(_ => Math.random() - .5):? Możesz nawet oszaleć i użyć operatora spreadu! Ale to jest teraz dla mnie zbyt ekscytujące.
Yeti

0

Trochę późno na imprezę, ale używam randojs.com do przypadkowości, ponieważ sprawia, że ​​takie rzeczy są bardzo łatwe. Możesz otrzymać losowo potasowaną tablicę liczb od 0 do 39, tak jak to:

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

Bez kłopotów z logistyką wszystkiego - dodatkowo jest super czytelny i łatwy do zrozumienia :)


0

Generatory

Tablica o długości 40 z 40 losowymi możliwymi wartościami (0 - 39) bez powtarzających się wartości jest lepsza do przetasowania, jak wyjaśniają @Phrogz i @Jared Beck. Innym podejściem, tylko dla zapisów, może być użycie generatorów. Ale to podejście jest mało wydajne w porównaniu z innymi proponowanymi rozwiązaniami .

function* generateRandomIterable(n, range) {
  for (let i = 0; i < n; i++) {
    yield ~~(Math.random() * range);
  }
}
const randomArr = [...generateRandomIterable(40,40)];
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.