Generowanie unikalnych liczb losowych od 1 do 100

Jak mogę wygenerować unikalne losowe liczby od 1 do 100 za pomocą JavaScript?

Author: Amin Soheyli, 2010-03-04

29 answers

Na przykład: aby wygenerować 8 unikalnych liczb losowych i zapisać je do tablicy, możesz po prostu to zrobić:

var arr = [];
while(arr.length < 8){
    var r = Math.floor(Math.random() * 100) + 1;
    if(arr.indexOf(r) === -1) arr.push(r);
}
console.log(arr);
 196
Author: adam0101,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-10-29 22:31:52
  1. wypełnij tablicę liczbami od 1 do 100.
  2. przetasuj to .
  3. weź pierwsze 8 elementów tablicy wynikowej.
 44
Author: ЯegDwight,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 10:31:30

Nowoczesne rozwiązanie JS za pomocą zestawu (i przeciętnego przypadku O (n))

const nums = new Set();
while(nums.size !== 8) {
  nums.add(Math.floor(Math.random() * 100) + 1);
}

console.log([...nums]);
 15
Author: Alister,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-11-20 10:08:59

Wygeneruj permutację ze 100 liczb, a następnie wybierz szeregowo.

Użycie algorytm Knutha Shuffle (aka The Fisher-Yates shuffle).

JavaScript:

  function fisherYates ( myArray,stop_count ) {
  var i = myArray.length;
  if ( i == 0 ) return false;
  int c = 0;
  while ( --i ) {
     var j = Math.floor( Math.random() * ( i + 1 ) );
     var tempi = myArray[i];
     var tempj = myArray[j];
     myArray[i] = tempj;
     myArray[j] = tempi;

     // Edited thanks to Frerich Raabe
     c++;
     if(c == stop_count)return;

   }
}

KOD SKOPIOWANY Z LINKU.

EDIT :

Poprawiony kod:

function fisherYates(myArray,nb_picks)
{
    for (i = myArray.length-1; i > 1  ; i--)
    {
        var r = Math.floor(Math.random()*i);
        var t = myArray[i];
        myArray[i] = myArray[r];
        myArray[r] = t;
    }

    return myArray.slice(0,nb_picks);
}

Potencjalny problem:

Załóżmy, że mamy tablicę 100 liczb {np. [1,2,3...100]} i przestajemy się wymieniać po 8 swapach; wtedy większość razy tablica będzie wyglądać jak {1,2,3,76,5,6,7,8,...liczby tutaj zostaną przetasowane ...10}.

Ponieważ każda liczba zostanie zamieniona z prawdopodobieństwem 1/100 więc prob. z zamiany pierwszych 8 liczb wynosi 8/100, natomiast prob. z zamiany pozostałych 92 to 92/100.

Ale jeśli uruchomimy algorytm dla pełnej tablicy, to jesteśmy pewni (prawie), że każdy wpis zostanie zamieniony.

W Przeciwnym Razie stajemy przed pytaniem: które 8 liczb wybrać?

 14
Author: Pratik Deoghare,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-03-05 10:49:04

Powyższe techniki są dobre, jeśli chcesz uniknąć biblioteki, ale w zależności od tego, czy będziesz w porządku z biblioteką, sugerowałbym sprawdzenie Chance do generowania losowych rzeczy w JavaScript.

Specjalnie, aby rozwiązać twoje pytanie, używając szansy, jest to tak proste, jak:

// One line!
var uniques = chance.unique(chance.natural, 8, {min: 1, max: 100});

// Print it out to the document for this snippet so we can see it in action
document.write(JSON.stringify(uniques));
<script src="http://chancejs.com/chance.min.js"></script>

Zastrzeżenie, jako autor przypadku, jestem trochę stronniczy ;)

 11
Author: Victor Quinn,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-12 03:43:06

Innym podejściem jest wygenerowanie tablicy 100 pozycji z rosnącymi liczbami i sortowanie jej losowo. Prowadzi to do naprawdę krótkiego i (moim zdaniem) prostego fragmentu.

const numbers = Array(100).fill().map((_, index) => index + 1);
numbers.sort(() => Math.random() - 0.5);
console.log(numbers.slice(0, 8));
 11
Author: Felix Lemke,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-05-25 13:02:37

Aby uniknąć długich i niepewnych tasowań, wykonałbym następujące czynności...

  1. Wygeneruj tablicę, która zawiera liczbę od 1 do 100, w kolejności.
  2. Wygeneruj losową liczbę od 1 do 100
  3. Spójrz w górę liczby w tym indeksie w tablicy i zapisz w swoich wynikach
  4. Usuń elemnt z tablicy, czyniąc go krótszym
  5. Powtórz od kroku 2, ale użyj 99 jako górnej granicy liczby losowej
  6. Powtórz od kroku 2, ale użyj 98 jako górnej limit liczby losowej
  7. Powtórz od kroku 2, ale użyj 97 jako górnej granicy liczby losowej
  8. Powtórz od kroku 2, ale użyj 96 jako górnej granicy liczby losowej
  9. Powtórz od kroku 2, ale użyj 95 jako górnej granicy liczby losowej
  10. Powtórz od kroku 2, ale użyj 94 jako górnej granicy liczby losowej
  11. Powtórz od kroku 2, ale użyj 93 jako górnej granicy liczby losowej
Voila-brak powtarzających się liczb.

I may napisz jakiś rzeczywisty kod później, jeśli ktoś jest zainteresowany.

Edit: to chyba passa konkurencji we mnie, ale po obejrzeniu postu @Alsciende, nie mogłem się oprzeć wrzuceniu kodu, który obiecałem.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<html>
<head>
<title>8 unique random number between 1 and 100</title>
<script type="text/javascript" language="Javascript">
    function pick(n, min, max){
        var values = [], i = max;
        while(i >= min) values.push(i--);
        var results = [];
        var maxIndex = max;
        for(i=1; i <= n; i++){
            maxIndex--;
            var index = Math.floor(maxIndex * Math.random());
            results.push(values[index]);
            values[index] = values[maxIndex];
        }
        return results;
    }
    function go(){
        var running = true;
        do{
            if(!confirm(pick(8, 1, 100).sort(function(a,b){return a - b;}))){
                running = false;
            }
        }while(running)
    }
</script>
</head>

<body>
    <h1>8 unique random number between 1 and 100</h1>
    <p><button onclick="go()">Click me</button> to start generating numbers.</p>
    <p>When the numbers appear, click OK to generate another set, or Cancel to stop.</p>
</body>

 8
Author: belugabob,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-03-05 08:45:34

Zrobiłbym to:

function randomInt(min, max) {
    return Math.round(min + Math.random()*(max-min));
}
var index = {}, numbers = [];
for (var i=0; i<8; ++i) {
    var number;
    do {
        number = randomInt(1, 100);
    } while (index.hasOwnProperty("_"+number));
    index["_"+number] = true;
    numbers.push(number);
}
delete index;
 3
Author: Gumbo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-03-04 15:32:10

Jest to bardzo ogólna funkcja, którą napisałem do generowania losowych unikalnych / nie unikalnych liczb całkowitych dla tablicy. Załóżmy, że ostatni parametr jest prawdziwy w tym scenariuszu dla tej odpowiedzi.

/* Creates an array of random integers between the range specified 
     len = length of the array you want to generate
     min = min value you require
     max = max value you require
     unique = whether you want unique or not (assume 'true' for this answer)
*/
    function _arrayRandom(len, min, max, unique) {
        var len = (len) ? len : 10,
                min = (min !== undefined) ? min : 1,
                max = (max !== undefined) ? max : 100,
                unique = (unique) ? unique : false,
                toReturn = [], tempObj = {}, i = 0;

        if(unique === true) {
            for(; i < len; i++) {
                var randomInt = Math.floor(Math.random() * ((max - min) + min));
                if(tempObj['key_'+ randomInt] === undefined) {
                    tempObj['key_'+ randomInt] = randomInt;
                    toReturn.push(randomInt);
                } else {
                    i--;
                }
            }
        } else {
            for(; i < len; i++) {
                toReturn.push(Math.floor(Math.random() * ((max - min) + min)));
            }
        }

        return toReturn;
    }

Tutaj 'tempObj' jest bardzo użytecznym obj, ponieważ każda wygenerowana liczba losowa bezpośrednio sprawdzi w tym tempObj, jeśli ten klucz już istnieje, jeśli nie, to zmniejszymy i o jeden, ponieważ potrzebujemy 1 dodatkowego biegu, ponieważ bieżąca liczba losowa już istnieje.

W Twoim przypadku uruchom po

_arrayRandom(8, 1, 100, true);
To wszystko.
 3
Author: kaizer1v,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-23 08:43:50

Tasowanie liczb od 1 do 100 jest właściwą strategią podstawową, ale jeśli potrzebujesz tylko 8 tasowanych liczb, nie ma potrzeby tasowania wszystkich 100 liczb.

Nie znam Javascript zbyt dobrze, ale wierzę, że łatwo jest szybko utworzyć tablicę 100 null. Następnie, przez 8 rund, zamieniasz n ' - ty element tablicy (n zaczyna się od 0) Na losowo wybrany element od n + 1 do 99. Oczywiście wszelkie elementy jeszcze nie wypełnione oznaczają, że element rzeczywiście byłby oryginalny indeks plus 1, więc to trywialne. Kiedy skończysz z 8 rundami, pierwsze 8 elementów tablicy będzie miało 8 tasowanych liczb.

 2
Author: Randal Schwartz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-03-04 17:20:52
var arr = []
while(arr.length < 8){
  var randomnumber=Math.ceil(Math.random()*100)
  if(arr.indexOf(randomnumber) === -1){arr.push(randomnumber)}  
}
document.write(arr);

Krótsze niż inne odpowiedzi, które widziałem

 2
Author: FFF,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-15 00:38:14

Ten sam algorytm permutacji co Zaklinacz maszyn, ale z prototypową implementacją. Lepiej nadaje się do dużej liczby typów. Używa js 1.7 przypisanie destrukcji jeśli jest dostępne.

// swaps elements at index i and j in array this
// swapping is easy on js 1.7 (feature detection)
Array.prototype.swap = (function () {
    var i=0, j=1;
    try { [i,j]=[j,i]; }
    catch (e) {}
    if(i) {
        return function(i,j) {
            [this[i],this[j]] = [this[j],this[i]];
            return this;
        }
    } else {
        return function(i,j) {
            var temp = this[i];
            this[i] = this[j];
            this[j] = temp;
            return this;
        }
    }
})();


// shuffles array this
Array.prototype.shuffle = function() {
    for(var i=this.length; i>1; i--) {
        this.swap(i-1, Math.floor(i*Math.random()));
    }
    return this;
}

// returns n unique random numbers between min and max
function pick(n, min, max) {
    var a = [], i = max;
    while(i >= min) a.push(i--);
    return a.shuffle().slice(0,n);
}

pick(8,1,100);

Edytuj: Inna propozycja, lepiej dopasowana do małej liczby typów, oparta na odpowiedzi belugaboba. Aby zagwarantować wyjątkowość, usuwamy wybrane liczby z tablicy.

// removes n random elements from array this
// and returns them
Array.prototype.pick = function(n) {
    if(!n || !this.length) return [];
    var i = Math.floor(this.length*Math.random());
    return this.splice(i,1).concat(this.pick(n-1));
}

// returns n unique random numbers between min and max
function pick(n, min, max) {
    var a = [], i = max;
    while(i >= min) a.push(i--);
    return a.pick(n);
}

pick(8,1,100);
 1
Author: Alsciende,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-03-05 09:07:43

Dla tablic z takimi dziurami [,2,,4,,6,7,,] bo moim problemem było wypełnienie tych dziur. Więc zmodyfikowałem go zgodnie z moimi potrzebami:)

Następujące zmodyfikowane rozwiązanie zadziałało dla mnie:)

var arr = [,2,,4,,6,7,,]; //example
while(arr.length < 9){
  var randomnumber=Math.floor(Math.random()*9+1);
  var found=false;
  for(var i=0;i<arr.length;i++){
    if(arr[i]==randomnumber){found=true;break;}
  }

  if(!found)
    for(k=0;k<9;k++)
    {if(!arr[k]) //if it's empty  !!MODIFICATION
      {arr[k]=randomnumber; break;}}
}

alert(arr); //outputs on the screen
 1
Author: Pulkit Chaudhri,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-11-03 20:53:50

Najlepszą wcześniejszą odpowiedzią jest Odpowiedź sje397. Otrzymasz tak dobre liczby losowe, jak to możliwe, tak szybko, jak to możliwe.

Moje rozwiązanie jest bardzo podobne do jego. Jednak czasami chcesz losowe liczby w losowej kolejności, i dlatego postanowiłem opublikować odpowiedź. Ponadto, zapewniam ogólną funkcję.
function selectKOutOfN(k, n) {
  if (k>n) throw "k>n";
  var selection = [];
  var sorted = [];
  for (var i = 0; i < k; i++) {
    var rand = Math.floor(Math.random()*(n - i));
    for (var j = 0; j < i; j++) {
      if (sorted[j]<=rand)
        rand++;
      else
        break;
    }
    selection.push(rand);
    sorted.splice(j, 0, rand);
  }
  return selection;
}

alert(selectKOutOfN(8, 100));
 1
Author: AndersTornkvist,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-19 13:19:34

Zaimplementowanie tego jako generatora sprawia, że praca z nim jest całkiem przyjemna. Uwaga, Ta implementacja różni się od tych, które wymagają najpierw przetasowania całej tablicy wejściowej.

Ta sample funkcja działa leniwie, dając 1 losowy przedmiot na iterację do N przedmiotów, o które prosisz. To miłe, bo jeśli tylko chcesz 3 pozycje z listy 1000, nie musisz dotykać wszystkich 1000 przedmiotów najpierw.

// sample :: Integer -> [a] -> [a]
const sample = n => function* (xs) {
  let ys = xs.slice(0);
  let len = xs.length;
  while (n > 0 && len > 0) {
    let i = (Math.random() * len) >> 0;
    yield ys.splice(i,1)[0];
    n--; len--;
  }
}

// example inputs
let items = ['a', 'b', 'c', 'd', 'e', 'f', 'g'];
let numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];

// get 3 random items
for (let i of sample(3) (items))
  console.log(i); // f g c

// partial application
const lotto = sample(3);
for (let i of lotto(numbers))
  console.log(i); // 3 8 7

// shuffle an array
const shuffle = xs => Array.from(sample (Infinity) (xs))
console.log(shuffle(items)) // [b c g f d e a]

Zdecydowałem się zaimplementować sample w sposób, który nie powoduje mutacji tablicy wejściowej, ale można łatwo argumentować, że implementacja mutująca jest korzystna.

Na przykład, funkcja shuffle może chcieć zmutować oryginalną tablicę wejściową. Możesz też chcieć pobierać próbki z tego samego wejścia w różnych momentach, aktualizując je za każdym razem.

// sample :: Integer -> [a] -> [a]
const sample = n => function* (xs) {
  let len = xs.length;
  while (n > 0 && len > 0) {
    let i = (Math.random() * len) >> 0;
    yield xs.splice(i,1)[0];
    n--; len--;
  }
}

// deal :: [Card] -> [Card]
const deal = xs => Array.from(sample (2) (xs));

// setup a deck of cards (13 in this case)
// cards :: [Card]
let cards = 'A234567890JQK'.split('');

// deal 6 players 2 cards each
// players :: [[Card]]
let players = Array.from(Array(6), $=> deal(cards))

console.log(players);
// [K, J], [6, 0], [2, 8], [Q, 7], [5, 4], [9, A]

// `cards` has been mutated. only 1 card remains in the deck
console.log(cards);
// [3]

sample nie jest już czystą funkcją ze względu na mutacja wejściowa tablicy, ale w pewnych okolicznościach (wykazana powyżej) może mieć większy sens.


Innym powodem, dla którego wybrałem generator zamiast funkcji, która po prostu zwraca tablicę, jest to, że możesz chcieć kontynuować próbkowanie aż do określonego warunku.

Być może chcę pierwszą liczbę pierwszą z listy 1,000,000 liczb losowych.

  • "ile powinienem próbki?"{–43]} - nie musisz określać
  • "Czy muszę znaleźć najpierw wszystkie liczby pierwsze, a potem wybierz losową liczbę pierwszą?" – Nie.
Ponieważ pracujemy z generatorem, to zadanie jest trywialne]}
const randomPrimeNumber = listOfNumbers => {
  for (let x of sample(Infinity) (listOfNumbers)) {
    if (isPrime(x))
      return x;
  }
  return NaN;
}

Będzie to ciągła próbka 1 liczby losowej na raz, x, sprawdź, czy jest pierwsza, a następnie zwróć x jeśli jest. Jeśli lista liczb zostanie wyczerpana przed znalezieniem liczby pierwszej, zwracane jest NaN.


Uwaga:

Ta odpowiedź została pierwotnie udostępniona na inne pytanie, które zostało zamknięte jako duplikat tego. Ponieważ bardzo różni się od innych rozwiązań tutaj, postanowiłem podzielić się nim również tutaj

 1
Author: Thank you,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:47:14

Oto moja wersja ES6, którą poukładałem. Jestem pewien, że to może być trochę bardziej skonsolidowane.

function randomArray(i, min, max) {
  min = Math.ceil(min);
  max = Math.floor(max);
  
  let arr = Array.from({length: i}, () => Math.floor(Math.random()* (max - min)) + min);
  
  return arr.sort();
 }
 
 let uniqueItems = [...new Set(randomArray(8, 0, 100))]
 console.log(uniqueItems);
 1
Author: Alex Mireles,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-08-10 09:30:43

Może użyjesz właściwości obiektu jako tabeli hash? W ten sposób najlepszym scenariuszem jest losowanie tylko 8 razy. Byłoby to skuteczne tylko, jeśli chcesz niewielką część zakresu liczb. Jest również znacznie mniej pamięci niż Fisher-Yates, ponieważ nie musisz przydzielać miejsca na tablicę.

var ht={}, i=rands=8;
while ( i>0 || keys(ht).length<rands) ht[Math.ceil(Math.random()*100)]=i--;
alert(keys(ht));

Potem dowiedziałem się, że obiekt.keys (obj) jest funkcją ECMAScript 5, więc powyższa funkcja jest teraz bezużyteczna w Internecie. Nie lękaj się, bo udało mi się Kompatybilny z ECMAScript 3 poprzez dodanie takiej funkcji klawiszy.

if (typeof keys == "undefined") 
{ 
  var keys = function(obj) 
  {
    props=[];
    for (k in ht) if (ht.hasOwnProperty(k)) props.push(k);
    return props;
  }
}
 0
Author: Jonas Elfström,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-03-05 14:23:06
var bombout=0;
var checkArr=[];
var arr=[];
while(arr.length < 8 && bombout<100){
  bombout++;
  var randomNumber=Math.ceil(Math.random()*100);
  if(typeof checkArr[randomNumber] == "undefined"){
    checkArr[randomNumber]=1;
    arr.push(randomNumber);
  }
}​

// untested - hence bombout
 0
Author: CPslashM,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-15 11:58:39

Jeśli potrzebujesz więcej unikalnych, musisz wygenerować tablicę (1..100).

var arr=[];
function generateRandoms(){
for(var i=1;i<=100;i++) arr.push(i);
}
function extractUniqueRandom()
{
   if (arr.length==0) generateRandoms();
   var randIndex=Math.floor(arr.length*Math.random());
   var result=arr[randIndex];
   arr.splice(randIndex,1);
   return result;

}
function extractUniqueRandomArray(n)
{
   var resultArr=[];
   for(var i=0;i<n;i++) resultArr.push(extractUniqueRandom());
   return resultArr;
}

Powyższy kod jest szybszy:
extractUniqueRandomArray (50)=> [2, 79, 38, 59, 63, 42, 52, 22, 78, 50, 39, 77, 1, 88, 40, 23, 48, 84, 91, 49, 4, 54, 93, 36, 100, 82, 62, 41, 89, 12, 24, 31, 86, 92, 64, 75, 70, 61, 67, 98, 76, 80, 56, 90, 83, 44, 43, 47, 7, 53]

 0
Author: MajidTaheri,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-04-15 07:15:08

Dodanie kolejnej lepszej wersji tego samego kodu (akceptowana odpowiedź) za pomocą funkcji JavaScript 1.6 indexOf. Nie trzeba zapętlać całej tablicy za każdym razem, gdy sprawdzasz duplikat.

var arr = []
while(arr.length < 8){
  var randomnumber=Math.ceil(Math.random()*100)
  var found=false;
    if(arr.indexOf(randomnumber) > -1){found=true;}
  if(!found)arr[arr.length]=randomnumber;
}

Starsza wersja Javascript może nadal używać wersji na górze

PS: próbowałem zasugerować aktualizację na wiki, ale została odrzucona. Nadal uważam, że to może być przydatne dla innych.

 0
Author: software.wikipedia,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-29 21:57:52

To jest moje osobiste rozwiązanie:

<script>

var i, k;
var numbers = new Array();
k = Math.floor((Math.random()*8));
numbers[0]=k;
    for (var j=1;j<8;j++){
        k = Math.floor((Math.random()*8));
i=0;
while (i < numbers.length){
if (numbers[i] == k){
    k = Math.floor((Math.random()*8));
    i=0;
}else {i++;}
}
numbers[j]=k;
    }
    for (var j=0;j<8;j++){
alert (numbers[j]);
    }
</script>

Losowo generuje 8 unikalnych wartości tablicy( od 0 do 7), a następnie wyświetla je za pomocą pola alarmowego.

 0
Author: Adam Atlas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-08 05:45:15
function getUniqueRandomNos() {
    var indexedArrayOfRandomNo = [];
    for (var i = 0; i < 100; i++) {
        var randNo = Math.random();
        indexedArrayOfRandomNo.push([i, randNo]);
    }
    indexedArrayOfRandomNo.sort(function (arr1, arr2) {
        return arr1[1] - arr2[1]
    });
    var uniqueRandNoArray = [];
    for (i = 0; i < 8; i++) {
        uniqueRandNoArray.push(indexedArrayOfRandomNo[i][0]);
    }
    return uniqueRandNoArray;
}

Myślę, że ta metoda różni się od metod podanych w większości odpowiedzi, więc pomyślałem, że mogę dodać odpowiedź tutaj (choć pytanie zostało zadane 4 lata temu).

Generujemy 100 losowych liczb i oznaczamy każdą z nich liczbami od 1 do 100. Następnie sortujemy te oznaczone liczbami losowymi, a znaczniki są tasowane losowo. Alternatywnie, w razie potrzeby w tym pytaniu, można pozbyć się tylko znalezienie top 8 oznaczonych liczb losowych. Znalezienie najlepszych 8 pozycji jest tańsze niż sortowanie całej tablicy.

Należy tutaj zauważyć, że algorytm sortowania wpływa na ten algorytm. Jeśli zastosowany algorytm sortowania jest stabilny, istnieje niewielkie odchylenie na korzyść mniejszych liczb. W idealnym przypadku chcielibyśmy, aby algorytm sortowania był niestabilny i nie był nawet tendencyjny w kierunku stabilności (lub niestabilności), aby uzyskać odpowiedź z idealnie jednolitym rozkładem prawdopodobieństwa.

 0
Author: Kartik Kale,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-11-12 14:17:30

To może obsłużyć generowanie do 20 cyfr unikalnej liczby losowej

JS

 var generatedNumbers = [];

    function generateRandomNumber(precision) { // input --> number precision in integer 
        if (precision <= 20) {
            var randomNum = Math.round(Math.random().toFixed(precision) * Math.pow(10, precision));
            if (generatedNumbers.indexOf(randomNum) > -1) {
                if (generatedNumbers.length == Math.pow(10, precision))
                    return "Generated all values with this precision";
                    return generateRandomNumber(precision);
            } else {
                generatedNumbers.push(randomNum);
                return randomNum;
            }
        } else
           return "Number Precision shoould not exceed 20";
    }
    generateRandomNumber(1);

Tutaj wpisz opis obrazka

JsFiddle

 0
Author: Nofi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-28 04:46:19

To rozwiązanie wykorzystuje hash, który jest znacznie bardziej wydajny O(1) niż sprawdzanie, czy znajduje się w tablicy. Ma też dodatkowe bezpieczne kontrole. Mam nadzieję, że to pomoże.

function uniqueArray(minRange, maxRange, arrayLength) {
  var arrayLength = (arrayLength) ? arrayLength : 10
  var minRange = (minRange !== undefined) ? minRange : 1
  var maxRange = (maxRange !== undefined) ? maxRange : 100
  var numberOfItemsInArray = 0
  var hash = {}
  var array = []

  if ( arrayLength > (maxRange - minRange) ) throw new Error('Cannot generate unique array: Array length too high')

  while(numberOfItemsInArray < arrayLength){
    // var randomNumber = Math.floor(Math.random() * (maxRange - minRange + 1) + minRange)
    // following line used for performance benefits
    var randomNumber = (Math.random() * (maxRange - minRange + 1) + minRange) << 0

    if (!hash[randomNumber]) {
      hash[randomNumber] = true
      array.push(randomNumber)
      numberOfItemsInArray++
    }
  }
  return array
}
document.write(uniqueArray(1, 100, 8))
 0
Author: RIdotCOM,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-21 13:04:51
getRandom (min, max) {
  return Math.floor(Math.random() * (max - min)) + min
}

getNRandom (min, max, n) {
  const numbers = []
  if (min > max) {
    return new Error('Max is gt min')
  }

  if (min === max) {
    return [min]
  }

  if ((max - min) >= n) {
    while (numbers.length < n) {
      let rand = this.getRandom(min, max + 1)
      if (numbers.indexOf(rand) === -1) {
        numbers.push(rand)
      }
    }
  }

  if ((max - min) < n) {
    for (let i = min; i <= max; i++) {
      numbers.push(i)
    }
  }
  return numbers
}
 0
Author: Oscar López,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-04 20:33:17

Użycie Set jest najszybszą opcją. Oto generyczna funkcja uzyskiwania unikalnego losowego, który wykorzystuje generator wywołania zwrotnego. Teraz jest Szybki i wielokrotnego użytku .

// Get a unique 'anything'
let unique = new Set()

function getUnique(generator) {
  let number = generator()
  while (!unique.add(number)) {
    number = generator()
  }
  return number;
}

// The generator.  Return anything, not just numbers.
const between_1_100 = () => 1 + Math.floor(Math.random() * 100)

// Test it
for (var i = 0; i < 8; i++) {
  const aNumber = getUnique(between_1_100)
}
// Dump the 'stored numbers'
console.log(Array.from(unique))
 0
Author: Steven Spungin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-25 11:37:19

Jest to implementacjaFisher Yates/Durstenfeld Shuffle , ale bez rzeczywistego tworzenia tablicy, co zmniejsza złożoność przestrzeni lub potrzebną pamięć, gdy rozmiar wyboru jest mały w porównaniu do liczby dostępnych elementów.

Aby wybrać 8 liczb ze 100, nie jest konieczne tworzenie tablicy 100 elementów.

Zakładając, że zostanie utworzona tablica,

  • z końca tablicy(100) uzyskaj liczbę losową (rnd) od 1 do 100
  • Swap 100 i liczba losowa rnd
  • Powtórz krok 1 za pomocą tablicy (99)

Jeśli tablica nie zostanie utworzona, można użyć hashmapy do zapamiętania rzeczywistych zamienionych pozycji. Gdy druga wygenerowana liczba losowa jest równa tej z wcześniej wygenerowanych liczb, Mapa podaje bieżącą wartość w tej pozycji, a nie rzeczywistą wartość.

const getRandom_ = (start, end) => {
  return Math.floor(Math.random() * (end - start + 1)) + start;
};
const getRealValue_ = (map, rnd) => {
  if (map.has(rnd)) {
    return getRealValue_(map, map.get(rnd));
  } else {
    return rnd;
  }
};
const getRandomNumbers = (n, start, end) => {
  const out = new Map();
  while (n--) {
    const rnd = getRandom_(start, end--);
    out.set(getRealValue_(out, rnd), end + 1);
  }
  return [...out.keys()];
};

console.info(getRandomNumbers(8, 1, 100));
console.info(getRandomNumbers(8, 1, Math.pow(10, 12)));
console.info(getRandomNumbers(800000, 1, Math.pow(10, 15)));
 0
Author: TheMaster,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-04-13 05:02:18

Oto przykład 5 losowych liczb pobranych z zakresu od 0 do 100 (zarówno 0, jak i 100 włącznie) bez powielania.

let finals = [];
const count = 5; // Considering 5 numbers
const max = 100;

for(let i = 0; i < max; i++){
  const rand = Math.round(Math.random() * max);
  !finals.includes(rand) && finals.push(rand)
}

finals = finals.slice(0, count)
 0
Author: gildniy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-07-10 15:40:45

Możesz też zrobić to z jednym linerem w ten sposób:

[...((add, set) => add(set, add))((set, add) => set.size < 8 ? add(set.add(Math.floor(Math.random()*100) + 1), add) : set, new Set())]

 -1
Author: Marcin Król,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-07 01:17:37