Bagaimana saya bisa menghasilkan beberapa angka acak unik antara 1 dan 100 menggunakan JavaScript?
javascript
random
integer
numbers
kotor
sumber
sumber
Jawaban:
Misalnya: Untuk menghasilkan 8 angka acak unik dan menyimpannya ke dalam array, Anda cukup melakukan ini:
sumber
Returns a random number between 0 (inclusive) and 1 (exclusive)
. Jikathe Math.random()
secara tidak sengaja mengembalikan 0,Math.ceil(0)
juga 0, meskipun kemungkinannya rendah.sumber
randlines file | head -10
.Hasilkan permutasi 100 angka dan kemudian pilih secara serial.
Gunakan Algoritma Knuth Shuffle (alias Fisher-Yates shuffle) .
JavaScript:
KODE DISALIN DARI LINK.
EDIT :
Kode yang ditingkatkan:
Potensi masalah:
Misalkan kita memiliki larik 100 angka {misalnya [1,2,3 ... 100]} dan kita berhenti bertukar setelah 8 swap; maka sebagian besar larik waktu akan terlihat seperti {1,2,3,76,5,6,7,8, ... angka di sini akan diacak ... 10}.
Karena setiap angka akan ditukar dengan probabilitas 1/100 jadi prob. dari menukar 8 angka pertama adalah 8/100 sedangkan prob. dari menukar 92 lainnya adalah 92/100.
Tetapi jika kita menjalankan algoritma untuk array penuh maka kita yakin (hampir) setiap entri ditukar.
Jika tidak, kita akan menghadapi pertanyaan: 8 nomor yang mana yang harus dipilih?
sumber
Solusi JS Modern menggunakan Set (dan rata-rata kasus O (n))
sumber
Math.floor(Math.random()*100) + 1
Set
di JS! Namun, bukankah solusi ini akan menyebabkan pembangkitan angka yang tidak perlu sampai salah satu memenuhi persyaratan keunikan, terutama pada iterasi terakhir, jika 8 mendekati 100? Jadi saya pikir saya lebih suka jawaban yang juga elegan dengan disort
bawah ini.Teknik di atas bagus jika Anda ingin menghindari perpustakaan, tetapi tergantung apakah Anda baik-baik saja dengan perpustakaan, saya sarankan memeriksa Peluang untuk menghasilkan hal-hal acak di JavaScript.
Secara khusus untuk menjawab pertanyaan Anda, menggunakan Chance semudah:
Penafian, sebagai penulis Chance, saya agak bias;)
sumber
var codes = chance.unique(chance.string, 8)
Jika Anda memerlukan kode yang ditarik dari kumpulan karakter tertentu, Anda dapat menentukannya seperti ini: dichance.unique(chance.string, 8, {pool: "abcd1234"})
mana abcd1234 dapat berupa karakter apa pun yang Anda inginkan dalam kumpulan tersebut. Lihat chancejs.com/#stringchance.string({ length: 8 })
dan jika Anda hanya ingin karakter tertentu muncul dalam string itu,chance.string({ pool: 'abcd1234', length: 8 })
yang akan mengembalikan string 8 karakter acak dari karakter abcd1234, jadi misalnya "2c2c44bc" atau "331141cc"Untuk menghindari pengocokan yang lama dan tidak dapat diandalkan, saya akan melakukan hal berikut ...
Voila - tidak ada nomor yang berulang.
Saya dapat memposting beberapa kode aktual nanti, jika ada yang tertarik.
Sunting: Ini mungkin pukulan kompetitif dalam diri saya tetapi, setelah melihat posting oleh @Alsciende, saya tidak bisa menahan untuk memposting kode yang saya janjikan.
sumber
Pendekatan lain adalah menghasilkan larik 100 item dengan angka naik dan mengurutkannya secara acak. Ini sebenarnya mengarah ke cuplikan yang sangat singkat dan (menurut saya) sederhana.
sumber
sort
diimplementasikan dengan baik, yang saya yakin itu).Saya akan melakukan ini:
sumber
Ini adalah fungsi yang sangat umum yang telah saya tulis untuk menghasilkan bilangan bulat unik / non-unik acak untuk sebuah array. Asumsikan parameter terakhir benar dalam skenario ini untuk jawaban ini.
Di sini 'tempObj' adalah objek yang sangat berguna karena setiap bilangan acak yang dihasilkan akan langsung memeriksa tempObj ini jika kunci itu sudah ada, jika belum, maka kita mengurangi i satu per satu karena kita perlu 1 operasi tambahan karena nomor acak saat ini sudah ada .
Dalam kasus Anda, jalankan perintah berikut
Itu saja.
sumber
min = (min) ? min : 1,
akan selalu mengembalikan 1. (jadi 0 tidak akan pernah dipilih)Mengocok angka dari 1 hingga 100 adalah strategi dasar yang tepat, tetapi jika Anda hanya membutuhkan 8 angka yang diacak, tidak perlu mengocok 100 angka.
Saya tidak terlalu paham Javascript, tapi saya yakin mudah untuk membuat array 100 null dengan cepat. Kemudian, untuk 8 putaran, Anda menukar elemen ke-n dari array (n mulai dari 0) dengan elemen yang dipilih secara acak dari n + 1 hingga 99. Tentu saja, setiap elemen yang belum terisi berarti bahwa elemen tersebut benar-benar telah menjadi indeks asli ditambah 1, jadi itu mudah untuk dijadikan faktor. Ketika Anda selesai dengan 8 putaran, 8 elemen pertama dari array Anda akan memiliki 8 angka yang diacak.
sumber
lebih pendek dari jawaban lain yang pernah saya lihat
sumber
Algoritme permutasi yang sama dengan The Machine Charmer, tetapi dengan implementasi prototipe. Lebih cocok untuk sejumlah besar pilihan. Menggunakan tugas penghancuran js 1.7 jika tersedia.
Sunting: Sebuah proposisi lain, lebih cocok untuk sejumlah kecil pilihan, berdasarkan jawaban belugabob. Untuk menjamin keunikan, kami menghapus nomor yang dipilih dari larik.
sumber
untuk array dengan lubang seperti ini
[,2,,4,,6,7,,]
karena masalah saya adalah mengisi lubang ini. Jadi saya memodifikasinya sesuai kebutuhan saya :)solusi yang dimodifikasi berikut berhasil untuk saya :)
sumber
Jawaban terbaik sebelumnya adalah jawaban oleh
sje397
. Anda akan mendapatkan nomor acak sebaik mungkin, secepat mungkin.Solusi saya sangat mirip dengan solusinya. Namun, terkadang Anda menginginkan nomor acak dalam urutan acak, dan itulah mengapa saya memutuskan untuk memposting jawaban. Selain itu, saya memberikan fungsi umum.
sumber
Ini adalah versi ES6 saya yang saya buat bersama. Saya yakin ini bisa sedikit lebih terkonsolidasi.
sumber
Bagaimana jika menggunakan properti objek sebagai tabel hash ? Dengan cara ini skenario terbaik Anda adalah hanya mengacak 8 kali. Ini hanya akan efektif jika Anda menginginkan sebagian kecil dari kisaran angka. Ini juga jauh lebih sedikit memori intensif daripada Fisher-Yates karena Anda tidak perlu mengalokasikan ruang untuk larik.
Saya kemudian menemukan bahwa Object.keys (obj) adalah fitur ECMAScript 5 jadi di atas cukup banyak tidak berguna di internet sekarang. Jangan takut, karena saya membuatnya kompatibel dengan ECMAScript 3 dengan menambahkan fungsi tombol seperti ini.
sumber
sumber
jika Anda membutuhkan lebih unik, Anda harus menghasilkan array (1..100).
kode di atas lebih cepat:
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]
sumber
Menambahkan versi lain yang lebih baik dari kode yang sama (jawaban diterima) dengan fungsi JavaScript 1.6 indexOf. Tidak perlu melakukan loop melalui seluruh array setiap kali Anda memeriksa duplikatnya.
Versi Javascript yang lebih lama masih dapat menggunakan versi di atas
PS: Mencoba menyarankan pembaruan ke wiki tetapi ditolak. Saya masih berpikir ini mungkin berguna untuk orang lain.
sumber
Ini adalah solusi pribadi saya:
Ini secara acak menghasilkan 8 nilai array unik (antara 0 dan 7), lalu menampilkannya menggunakan kotak peringatan.
sumber
Saya pikir metode ini berbeda dari metode yang diberikan di sebagian besar jawaban, jadi saya pikir saya dapat menambahkan jawaban di sini (meskipun pertanyaan itu diajukan 4 tahun yang lalu).
Kami menghasilkan 100 nomor acak, dan menandai masing-masing nomor dengan nomor dari 1 hingga 100. Kemudian kami menyortir nomor acak yang ditandai ini, dan tag dikocok secara acak. Atau, sesuai kebutuhan dalam pertanyaan ini, seseorang dapat menghapus hanya dengan menemukan 8 teratas dari nomor acak yang diberi tag. Menemukan 8 item teratas lebih murah daripada menyortir seluruh larik.
Perlu dicatat di sini, bahwa algoritma pengurutan mempengaruhi algoritma ini. Jika algoritme pengurutan yang digunakan stabil, ada sedikit bias yang mendukung jumlah yang lebih kecil. Idealnya, kita ingin algoritma pengurutan tidak stabil dan bahkan tidak bias terhadap stabilitas (atau ketidakstabilan) untuk menghasilkan jawaban dengan distribusi probabilitas yang seragam secara sempurna.
sumber
Ini dapat menangani pembuatan hingga 20 digit nomor acak UNIK
JS
jsFiddle
sumber
Solusi ini menggunakan hash yang lebih berkinerja O (1) daripada memeriksa apakah berada dalam array. Ini memiliki pemeriksaan ekstra aman juga. Semoga membantu.
sumber
Menerapkan ini sebagai generator membuatnya cukup bagus untuk digunakan. Perhatikan, implementasi ini berbeda dari implementasi yang mengharuskan seluruh larik input diacak terlebih dahulu.
Saya memilih untuk menerapkan
sample
dengan cara yang tidak mengubah array input, tetapi Anda dapat dengan mudah membantah bahwa implementasi yang bermutasi lebih baik.Misalnya,
shuffle
fungsi tersebut mungkin ingin mengubah larik input asli. Atau Anda mungkin ingin mengambil sampel dari masukan yang sama di waktu yang berbeda, memperbarui masukan setiap saat.sample
bukan lagi fungsi murni karena mutasi input larik, tetapi dalam keadaan tertentu (ditunjukkan di atas) mungkin lebih masuk akal.Alasan lain saya memilih generator daripada fungsi yang hanya mengembalikan array adalah karena Anda mungkin ingin melanjutkan pengambilan sampel hingga kondisi tertentu.
Mungkin saya ingin bilangan prima pertama dari daftar 1.000.000 bilangan acak.
Karena kita bekerja dengan generator, tugas ini tidak terlalu rumit
Ini akan terus menerus mengambil sampel 1 bilangan acak pada satu waktu
x
,, periksa apakah bilangan prima, lalu kembalikanx
jika bilangan tersebut. Jika daftar bilangan habis sebelum bilangan prima ditemukan,NaN
dikembalikan.catatan:
Jawaban ini awalnya dibagikan pada pertanyaan lain yang ditutup sebagai duplikat dari pertanyaan ini. Karena sangat berbeda dari solusi lain yang disediakan di sini, saya memutuskan untuk membagikannya di sini juga
sumber
sumber
Menggunakan a
Set
adalah opsi tercepat Anda. Berikut adalah fungsi umum untuk mendapatkan acak unik yang menggunakan generator panggilan balik. Sekarang cepat dan dapat digunakan kembali .sumber
Ini adalah implementasi Fisher Yates / Durstenfeld Shuffle , tetapi tanpa pembuatan larik yang sebenarnya sehingga mengurangi kompleksitas ruang atau memori yang dibutuhkan, ketika ukuran pilihan kecil dibandingkan dengan jumlah elemen yang tersedia.
Untuk memilih 8 angka dari 100, tidak perlu membuat larik yang terdiri dari 100 elemen.
Dengan asumsi sebuah array dibuat,
rnd
) dari 1 hingga 100rnd
Jika sebuah array tidak dibuat, hashMap dapat digunakan untuk mengingat posisi yang sebenarnya ditukar. Ketika bilangan acak kedua yang dihasilkan sama dengan salah satu bilangan yang dihasilkan sebelumnya, peta memberikan nilai saat ini di posisi itu daripada nilai sebenarnya.
sumber
Berikut adalah contoh 5 angka acak yang diambil dari rentang 0 hingga 100 (termasuk 0 dan 100) tanpa duplikasi.
sumber
Anda juga dapat melakukannya dengan satu liner seperti ini:
[...((add, set) => add(set, add))((set, add) => set.size < 8 ? add(set.add(Math.floor(Math.random()*100) + 1), add) : set, new Set())]
sumber