Jak mogę wygenerować unikalne liczby losowe od 1 do 100 za pomocą JavaScript?
javascript
random
integer
numbers
rozsiany
źródło
źródło
Odpowiedzi:
Na przykład: Aby wygenerować 8 unikalnych liczb losowych i zapisać je w tablicy, możesz po prostu zrobić to:
źródło
Returns a random number between 0 (inclusive) and 1 (exclusive)
. Jeślithe Math.random()
przypadkowo zwróci 0,Math.ceil(0)
to również wynosi 0, chociaż szansa jest mała.źródło
randlines file | head -10
.Generować permutację 100 liczb, a następnie wybierz kolejno.
Użyj algorytmu tasowania Knutha (inaczej tasowania Fishera-Yatesa) .
JavaScript:
KOD SKOPIOWANY Z LINKU.
EDYTOWAĆ :
Ulepszony kod:
Potencjalny problem:
Załóżmy, że mamy tablicę 100 liczb {np. [1, 2, 3 ... 100]} i przestajemy zmieniać po 8 zamianach; wtedy przez większość czasów tablica będzie wyglądać następująco: {1, 2, 3, 76, 6, 7, 8, ... liczby tutaj zostaną przetasowane ... 10}.
Ponieważ każda liczba zostanie zamieniona z prawdopodobieństwem 1/100, więc prawdopodobieństwo. zamiany pierwszych 8 liczb to 8/100, podczas gdy prawd. zamiany innych 92 to 92/100.
Ale jeśli uruchomimy algorytm dla pełnej tablicy, jesteśmy pewni (prawie) każdy wpis zostanie zamieniony.
W przeciwnym razie stajemy przed pytaniem: które 8 liczb wybrać?
źródło
Nowoczesne rozwiązanie JS wykorzystujące Set (i średni przypadek O (n))
źródło
Math.floor(Math.random()*100) + 1
Set
w JS! Jednak czy to rozwiązanie nie powodowałoby niepotrzebnego generowania liczb, dopóki nie spełni się wymogu unikalności, szczególnie w ostatnich iteracjach, gdyby 8 było bliższe 100? Dlatego myślę, że wolę również elegancką odpowiedźsort
poniżej.Powyższe techniki są dobre, jeśli chcesz uniknąć biblioteki, ale w zależności od tego, czy nie masz nic przeciwko bibliotece, sugerowałbym sprawdzenie Szansa na generowanie losowych rzeczy w JavaScript.
W szczególności, aby rozwiązać swoje pytanie, korzystanie z Chance jest tak proste, jak:
Zastrzeżenie, jako autor Chance jestem nieco stronniczy;)
źródło
var codes = chance.unique(chance.string, 8)
Jeśli potrzebujesz kodów pobranych z określonej puli znaków, możesz to określić w ten sposób:chance.unique(chance.string, 8, {pool: "abcd1234"})
gdzie abcd1234 może być dowolnymi znakami, które chcesz w puli. Zobacz chancejs.com/#stringchance.string({ length: 8 })
i jeśli chcesz, aby w tym ciągu pojawiały się tylko określone znaki,chance.string({ pool: 'abcd1234', length: 8 })
co zwróci losowy ciąg 8 znaków ze znaków abcd1234, na przykład „2c2c44bc” lub „331141cc”Aby uniknąć długich i zawodnych przetasowań, zrobiłbym następujące rzeczy ...
Voila - bez powtarzających się liczb.
Jeśli ktoś jest zainteresowany, mogę wysłać później jakiś rzeczywisty kod.
Edycja: Prawdopodobnie to moja passa konkurencyjna, ale widząc post @Alsciende, nie mogłem się powstrzymać przed wysłaniem obiecanego kodu.
źródło
Innym podejściem jest wygenerowanie tablicy zawierającej 100 elementów z rosnącymi liczbami i losowe sortowanie. Prowadzi to właściwie do naprawdę krótkiego i (moim zdaniem) prostego fragmentu.
źródło
sort
jest dobrze zaimplementowany, co na pewno jest).Zrobiłbym to:
źródło
Jest to bardzo ogólna funkcja, którą napisałem, aby generować losowe unikalne / nieunikalne liczby całkowite dla tablicy. Załóżmy, że ostatni parametr jest prawdziwy w tym scenariuszu dla tej odpowiedzi.
Tutaj `` tempObj '' jest bardzo użytecznym obiektem, ponieważ każda wygenerowana liczba losowa będzie bezpośrednio sprawdzać w tym tempObj, jeśli ten klucz już istnieje, jeśli nie, to zmniejszamy i o jeden, ponieważ potrzebujemy 1 dodatkowego uruchomienia, ponieważ bieżąca liczba losowa już istnieje .
W twoim przypadku wykonaj następujące czynności
To wszystko.
źródło
min = (min) ? min : 1,
zawsze zwraca 1. (więc 0 nigdy nie zostanie wybrane)Tasowanie liczb od 1 do 100 to właściwa podstawowa strategia, ale jeśli potrzebujesz tylko 8 tasowanych liczb, nie ma potrzeby tasowania wszystkich 100 liczb.
Nie znam za dobrze Javascript, ale uważam, że łatwo jest szybko utworzyć tablicę 100 wartości null. Następnie przez 8 rund zamieniasz n-ty element tablicy (n zaczynając od 0) na losowo wybrany element z przedziału od n + 1 do 99. Oczywiście wszelkie elementy, które nie zostały jeszcze wypełnione, oznaczają, że element byłby naprawdę oryginalny indeks plus 1, więc jest to trywialne do uwzględnienia. Kiedy skończysz z 8 rundami, pierwszych 8 elementów tablicy będzie miało 8 tasowanych liczb.
źródło
krócej niż inne odpowiedzi, które widziałem
źródło
Ten sam algorytm permutacji co w The Machine Charmer, ale z prototypową implementacją. Lepiej nadaje się do dużej liczby kilofów. Używa przydziału destrukturyzacji js 1.7, jeśli jest dostępny.
Edycja: inna propozycja, lepiej dopasowana do małej liczby typów, oparta na odpowiedzi Belugaboba. Aby zagwarantować unikalność, usuwamy wybrane liczby z tablicy.
źródło
dla tablic z takimi dziurami,
[,2,,4,,6,7,,]
ponieważ moim problemem było wypełnienie tych dziur. Więc zmodyfikowałem go zgodnie z moimi potrzebami :)poniższe zmodyfikowane rozwiązanie zadziałało u mnie :)
źródło
Najlepszą wcześniejszą odpowiedzią jest odpowiedź wg
sje397
. Otrzymasz jak najlepsze liczby losowe, tak szybko, jak to możliwe.Moje rozwiązanie jest bardzo podobne do jego rozwiązania. Czasami jednak chcesz losowe liczby w losowej kolejności i dlatego zdecydowałem się wysłać odpowiedź. Ponadto zapewniam ogólną funkcję.
źródło
Oto moja wersja ES6, którą zebrałem razem. Jestem pewien, że może być trochę bardziej skonsolidowany.
źródło
A co powiesz na użycie właściwości obiektu jako tablicy skrótów ? W ten sposób najlepszym scenariuszem jest losowanie tylko 8 razy. Byłoby to skuteczne tylko wtedy, gdy chcesz mieć niewielką część zakresu liczb. Zajmuje również znacznie mniej pamięci niż Fisher-Yates, ponieważ nie musisz przydzielać miejsca na tablicę.
Potem dowiedziałem się, że Object.keys (obj) jest funkcją ECMAScript 5, więc powyższe jest obecnie praktycznie bezużyteczne w sieciach internetowych. Nie bój się, ponieważ dostosowałem go do ECMAScript 3, dodając taką funkcję klawiszy.
źródło
źródło
jeśli potrzebujesz więcej unikatowości, musisz wygenerować tablicę (1..100).
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]
źródło
Dodanie kolejnej lepszej wersji tego samego kodu (zaakceptowana odpowiedź) z funkcją indexOf w JavaScript 1.6. Nie ma potrzeby przechodzenia przez całą tablicę za każdym razem, gdy sprawdzasz duplikat.
Starsza wersja Javascript może nadal korzystać z wersji u góry
PS: Próbowałem zasugerować aktualizację wiki, ale została odrzucona. Nadal uważam, że może to być przydatne dla innych.
źródło
To jest moje osobiste rozwiązanie:
Losowo generuje 8 unikalnych wartości tablicowych (od 0 do 7), a następnie wyświetla je za pomocą pola ostrzegawczego.
źródło
Myślę, że ta metoda różni się od metod podanych w większości odpowiedzi, więc pomyślałem, że mógłbym tu dodać odpowiedź (chociaż pytanie zadano 4 lata temu).
Generujemy 100 losowych liczb i oznaczamy każdą z nich liczbami od 1 do 100. Następnie sortujemy te otagowane liczby losowe, a tagi są losowo tasowane. Alternatywnie, w razie potrzeby w tym pytaniu, można by pozbyć się po prostu znalezienia 8 pierwszych oznaczonych liczb losowych. Znalezienie 8 najlepszych elementów 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. Idealnie byłoby, gdyby algorytm sortowania był niestabilny i nawet nie był nastawiony na stabilność (lub niestabilność), aby uzyskać odpowiedź z idealnie jednorodnym rozkładem prawdopodobieństwa.
źródło
Może to obsłużyć generowanie do 20 cyfr UNIKALNEJ liczby losowej
JS
jsFiddle
źródło
To rozwiązanie używa skrótu, który jest znacznie wydajniejszy O (1) niż sprawdzenie, czy rezyduje w tablicy. Ma również dodatkowe bezpieczne kontrole. Mam nadzieję, że to pomoże.
źródło
Implementacja 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.
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
shuffle
funkcja może chcieć zmodyfikować oryginalną tablicę wejściową. Lub możesz chcieć próbkować z tego samego wejścia w różnych momentach, aktualizując wejście za każdym razem.sample
nie jest już czystą funkcją z powodu mutacji wejścia tablicy, ale w pewnych okolicznościach (pokazanych powyżej) może mieć więcej sensu.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 do określonego warunku.
Być może chcę pierwszą liczbę pierwszą z listy 1 000 000 liczb losowych.
Ponieważ pracujemy z generatorem, to zadanie jest banalne
Spowoduje to ciągłe próbkowanie 1 losowej liczby naraz
x
, sprawdź, czy jest to liczba pierwsza, a następnie zwróci,x
jeśli tak jest. Jeśli lista liczb zostanie wyczerpana przed znalezieniem liczby pierwszej,NaN
zwracana jest wartość.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 przedstawionych tutaj rozwiązań, postanowiłem się nim również podzielić
źródło
źródło
Korzystanie z a
Set
to najszybsza opcja. Oto ogólna funkcja do uzyskiwania unikalnej liczby losowej, która używa generatora wywołań zwrotnych. Teraz jest szybki i wielokrotnego użytku .źródło
Jest to implementacja Shuffle Fisher Yates / Durstenfeld , ale bez faktycznego tworzenia tablicy, co zmniejsza złożoność przestrzeni lub ilość potrzebnej pamięci, gdy rozmiar pobrania jest mały w porównaniu z liczbą dostępnych elementów.
Aby wybrać 8 liczb ze 100, nie jest konieczne tworzenie tablicy 100 elementów.
Zakładając, że utworzono tablicę,
rnd
) od 1 do 100rnd
Jeśli tablica nie zostanie utworzona, można użyć mapy hashMap do zapamiętania rzeczywistych zamienionych pozycji. Kiedy druga wygenerowana liczba losowa jest równa jednej z poprzednio wygenerowanych liczb, mapa podaje bieżącą wartość w tej pozycji, a nie rzeczywistą wartość.
źródło
Oto przykład losowych 5 liczb z zakresu od 0 do 100 (w tym 0 i 100) bez powielania.
źródło
Możesz to również zrobić za pomocą jednej wkładki 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())]
źródło