JavaScript kullanarak 1 ile 100 arasında bazı benzersiz rastgele sayıları nasıl oluşturabilirim ?
JavaScript kullanarak 1 ile 100 arasında bazı benzersiz rastgele sayıları nasıl oluşturabilirim ?
Yanıtlar:
Örneğin: 8 benzersiz rastgele sayı oluşturmak ve bunları bir dizide saklamak için, bunu yapmanız yeterlidir:
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);
Returns a random number between 0 (inclusive) and 1 (exclusive)
. Eğer the Math.random()
yanlışlıkla 0 döndürür, Math.ceil(0)
şans düşük olsa da 0'dır.
randlines file | head -10
.
100 sayının permütasyonunu oluşturun ve ardından seri olarak seçin.
Kullanım Knuth Karıştır (aka Fisher-Yates karıştır) Algoritması .
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;
}
}
DÜZENLE :
Geliştirilmiş 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);
}
Potansiyel problem:
Diyelim ki 100 sayılık bir dizimiz var {ör. [1,2,3 ... 100]} ve 8 takasdan sonra değiş tokuşu durduruyoruz; daha sonra çoğu kez dizisi {1,2,3,76,5,6,7,8, ... gibi görünecek, buradaki sayılar karıştırılacak ... 10}.
Çünkü her sayı 1/100 olasılıkla yer değiştirecek yani prob. ilk 8 sayıyı değiştirme oranı 8/100 iken prob. diğer 92 takas oranı 92/100.
Ancak tam dizi için algoritma çalıştırırsak, o zaman (neredeyse) her girişin değiştirildiğinden eminiz.
Aksi takdirde bir soruyla karşılaşırız: hangi 8 rakamı seçmeliyiz?
Set kullanarak modern JS Çözümü (ve ortalama durum O (n))
const nums = new Set();
while(nums.size !== 8) {
nums.add(Math.floor(Math.random() * 100) + 1);
}
console.log([...nums]);
Math.floor(Math.random()*100) + 1
Set
JS'de keşfetmek çok güzel ! Bununla birlikte, bu çözüm, özellikle son yinelemelerde, 8, 100'e yakın olsaydı, benzersizlik gerekliliğine uyana kadar gereksiz sayı üretimine neden olmaz mıydı? Bu nedenle sort
aşağıdaki şık yanıtı tercih ettiğimi düşünüyorum .
Yukarıdaki teknikler kütüphane kaçınmak istiyorsanız iyi, ama bir kütüphane ile düzeleceğine, ben kontrol öneririz bağlı Chance JavaScript rastgele şeyler üretmek için.
Özellikle sorunuzu çözmek için Chance'i kullanmak şu kadar kolaydır:
// 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>
Feragatname, Chance'in yazarı olarak biraz önyargılıyım;)
var codes = chance.unique(chance.string, 8)
Belirli bir karakter havuzundan alınan kodlara ihtiyacınız varsa, bunu şöyle belirtebilirsiniz: chance.unique(chance.string, 8, {pool: "abcd1234"})
burada abcd1234 havuzda istediğiniz herhangi bir karakter olabilir. Bkz chancejs.com/#string
chance.string({ length: 8 })
ve bu dizede yalnızca belirli karakterlerin görünmesini istiyorsanız, chance.string({ pool: 'abcd1234', length: 8 })
bu, abcd1234 karakterlerinden rastgele 8 karakterlik bir dizi döndürür, örneğin "2c2c44bc" veya "331141cc"
Diğer bir yaklaşım, artan sayılarla 100 maddelik bir dizi oluşturmak ve bunu rastgele sıralamaktır. Bu aslında gerçekten kısa ve (bence) basit bir parçaya götürüyor.
const numbers = Array(100).fill().map((_, index) => index + 1);
numbers.sort(() => Math.random() - 0.5);
console.log(numbers.slice(0, 8));
sort
eminim ki iyi uygulanmıştır).
Uzun ve güvenilmez karıştırmalardan kaçınmak için aşağıdakileri yapardım ...
Voila - tekrarlanan numara yok.
İlgilenen varsa, daha sonra gerçek bir kod gönderebilirim.
Düzenleme: Muhtemelen içimdeki rekabetçi galibiyet ama @ Alsciende'nin gönderisini gördükten sonra söz verdiğim kodu göndermeye karşı koyamadım.
<!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>
Bunu yapardım:
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;
Bu, bir dizi için rastgele benzersiz / benzersiz olmayan tamsayılar oluşturmak için yazdığım çok genel bir işlevdir. Bu yanıt için bu senaryoda son parametrenin doğru olduğunu varsayın.
/* 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;
}
Burada 'tempObj' çok kullanışlı bir objedir, çünkü üretilen her rasgele sayı bu tempObj'yi doğrudan kontrol edecektir, eğer bu anahtar zaten mevcutsa, değilse, o zaman i'yi bir azaltıyoruz çünkü mevcut rasgele sayı zaten mevcut olduğundan fazladan 1 çalışmaya ihtiyacımız var .
Sizin durumunuzda aşağıdakileri çalıştırın
_arrayRandom(8, 1, 100, true);
Bu kadar.
min = (min) ? min : 1,
her zaman 1 değerini döndürür (bu nedenle 0 asla seçilmeyecektir)
Sayıları 1'den 100'e kadar karıştırmak doğru temel stratejidir, ancak yalnızca 8 karıştırılmış sayıya ihtiyacınız varsa, 100 sayının tümünü karıştırmanıza gerek yoktur.
Javascript'i çok iyi bilmiyorum, ancak hızlı bir şekilde 100 sıfırlık bir dizi oluşturmanın kolay olduğuna inanıyorum. Ardından, 8 tur için, dizinin n'inci öğesini (0'dan başlayan n) n + 1'den 99'a kadar rastgele seçilen bir öğe ile değiştirirsiniz. Elbette, henüz doldurulmamış herhangi bir öğe, öğenin gerçekten olduğu anlamına gelir orijinal indeks artı 1, yani çarpanlara ayırmak önemsizdir. 8 turla işiniz bittiğinde, dizinizin ilk 8 öğesinde 8 karıştırılmış sayınız olacaktır.
The Machine Charmer ile aynı permütasyon algoritması, ancak prototiplenmiş bir uygulama ile. Çok sayıda seçim için daha uygun. Varsa js 1.7 imha atamasını kullanır .
// 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);
Düzenleme: Belugabob'un cevabına dayanan, az sayıdaki seçim için daha uygun olan başka bir teklif. Benzersizliği garantilemek için, seçilen sayıları diziden kaldırıyoruz.
// 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);
bunun gibi delikli diziler için [,2,,4,,6,7,,]
çünkü benim sorunum bu boşlukları doldurmaktı. Bu yüzden ihtiyacıma göre değiştirdim :)
aşağıdaki değiştirilmiş çözüm benim için çalıştı :)
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
Daha önceki en iyi cevap, tarafından verilen cevaptır sje397
. Mümkün olduğunca çabuk, alabildiğiniz kadar iyi rastgele sayılar alacaksınız.
Benim çözümüm onun çözümüne çok benziyor. Bununla birlikte, bazen rastgele sayıları rastgele sırada istersiniz ve bu yüzden bir cevap göndermeye karar verdim. Ek olarak, genel bir işlev sağlıyorum.
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));
İşte birlikte döşediğim ES6 versiyonum. Eminim biraz daha konsolide olabilir.
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);
Nesne özelliklerini bir hash tablosu olarak kullanmaya ne dersiniz ? Bu şekilde, en iyi senaryonuz yalnızca 8 kez rastgele seçim yapmaktır. Yalnızca sayı aralığının küçük bir bölümünü istiyorsanız etkili olur. Ayrıca Fisher-Yates'ten çok daha az bellek yoğun çünkü bir dizi için yer ayırmanız gerekmiyor.
var ht={}, i=rands=8;
while ( i>0 || keys(ht).length<rands) ht[Math.ceil(Math.random()*100)]=i--;
alert(keys(ht));
Daha sonra Object.keys (obj) ' in bir ECMAScript 5 özelliği olduğunu öğrendim , bu yüzden yukarıdakiler şu anda internette hemen hemen işe yaramaz. Korkmayın, çünkü ECMAScript 3'ü böyle bir tuş işlevi ekleyerek uyumlu hale getirdim.
if (typeof keys == "undefined")
{
var keys = function(obj)
{
props=[];
for (k in ht) if (ht.hasOwnProperty(k)) props.push(k);
return props;
}
}
Daha fazla benzersizliğe ihtiyacınız varsa bir dizi (1..100) oluşturmalısınız.
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;
}
yukarıdaki kod daha hızlıdır:
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]
JavaScript 1.6 indexOf işlevi ile aynı kodun daha iyi bir sürümünü (kabul edilen yanıt) eklemek. Yinelenen kopyayı her kontrol ettiğinizde tüm dizide döngü oluşturmanıza gerek yoktur.
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;
}
Javascript'in eski sürümü yine de üstteki sürümü kullanabilir
Not: Wiki'ye bir güncelleme önermeye çalıştım ama reddedildi. Hala başkaları için faydalı olabileceğini düşünüyorum.
Bu benim kişisel çözümüm:
<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>
Rastgele olarak 8 benzersiz dizi değeri oluşturur (0 ile 7 arasında), ardından bunları bir uyarı kutusu kullanarak görüntüler.
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;
}
Bu yöntemin yanıtların çoğunda verilen yöntemlerden farklı olduğunu düşünüyorum, bu yüzden buraya bir cevap ekleyebileceğimi düşündüm (soru 4 yıl önce sorulmuş olmasına rağmen).
100 rastgele sayı üretiriz ve her birini 1'den 100'e kadar sayılarla etiketleriz. Daha sonra bu etiketli rastgele sayıları sıralarız ve etiketler rastgele karıştırılır. Alternatif olarak, bu soruda gerektiği gibi, etiketli rastgele sayıların ilk 8'ini bulmak da ortadan kaldırılabilir. İlk 8 öğeyi bulmak, tüm diziyi sıralamaktan daha ucuzdur.
Burada, sıralama algoritmasının bu algoritmayı etkilediği unutulmamalıdır. Kullanılan sıralama algoritması kararlıysa, daha küçük sayılar lehine küçük bir önyargı vardır. İdeal olarak, mükemmel bir şekilde tekdüze olasılık dağılımına sahip bir yanıt üretmek için sıralama algoritmasının istikrarsız olmasını ve hatta kararlılığa (veya istikrarsızlığa) yönelik önyargılı olmamasını isteriz.
Bu, 20 haneye kadar BENZERSİZ rasgele sayı üretmeyi başarabilir
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);
Bu çözüm, dizide yer alıp almadığını kontrol etmekten çok daha yüksek performanslı O (1) olan karmayı kullanır. Ekstra güvenli çekleri de vardır. Umarım yardımcı olur.
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))
Bunu bir jeneratör olarak uygulamak, çalışmayı oldukça güzel kılar. Unutmayın, bu uygulama, önce tüm girdi dizisinin karıştırılmasını gerektirenlerden farklıdır.
Bu
sample
işlev tembel çalışır ve istediğiniz öğeye kadar yineleme başına 1 rastgele öğeN
verir. Bu güzel, çünkü 1000'lik bir listeden yalnızca 3 öğe istiyorsanız , önce 1000 öğenin tamamına dokunmanız gerekmez.
// 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]
sample
Girdi dizisini değiştirmeyecek bir şekilde uygulamayı seçtim , ancak bir mutasyon uygulamasının elverişli olduğunu kolayca iddia edebilirsiniz.
Örneğin, shuffle
işlev orijinal girdi dizisini değiştirmeyi isteyebilir. Veya aynı girişten çeşitli zamanlarda örnekleme yapmak ve girişi her seferinde güncellemek isteyebilirsiniz.
// 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
dizi girdisi mutasyonu nedeniyle artık saf bir işlev değildir, ancak bazı durumlarda (yukarıda gösterilmiştir) daha mantıklı olabilir.
Sadece bir dizi döndüren bir işlev yerine bir üreteç seçmemin bir başka nedeni, belirli bir koşula kadar örneklemeye devam etmek isteyebilmenizdir.
Belki de 1.000.000 rastgele sayı listesinden ilk asal sayıyı istiyorum.
Bir jeneratörle çalıştığımız için bu görev önemsiz
const randomPrimeNumber = listOfNumbers => {
for (let x of sample(Infinity) (listOfNumbers)) {
if (isPrime(x))
return x;
}
return NaN;
}
Bu, sürekli olarak bir seferde 1 rastgele sayıyı örnekleyecek, x
asal olup olmadığını kontrol edecek, sonra ise geri dönecektir x
. Bir asal bulunmadan önce sayılar listesi tükenirse NaN
döndürülür.
Not:
Bu cevap başlangıçta, bunun kopyası olarak kapatılan başka bir soruda paylaşıldı. Burada sunulan diğer çözümlerden çok farklı olduğu için burada da paylaşmaya karar verdim
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
}
A kullanmak Set
en hızlı seçeneğinizdir. Bir geri arama oluşturucu kullanan benzersiz bir rastgele elde etmek için genel bir işlev. Şimdi hızlı ve tekrar kullanılabilir .
// 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))
Bu, Fisher Yates / Durstenfeld Shuffle'ın bir uygulamasıdır , ancak gerçek bir dizi yaratılmadan, toplama boyutu mevcut elemanların sayısına kıyasla küçük olduğunda alan karmaşıklığını veya gereken belleği azaltır.
100'den 8 sayı seçmek için 100 elemanlık bir dizi oluşturmak gerekli değildir.
Bir dizinin oluşturulduğunu varsayarsak,
rnd
1'den 100'e kadar rastgele sayı ( ) alın rnd
Bir dizi oluşturulmazsa, gerçek değiştirilen konumları hatırlamak için bir hashMap kullanılabilir. Üretilen ikinci rasgele sayı, daha önce üretilen sayılardan birine eşit olduğunda, harita, gerçek değer yerine o konumdaki geçerli değeri sağlar.
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)));
Burada, 0 ile 100 aralığından (hem 0 hem de 100 dahil) alınan ve hiçbir çoğaltma yapılmadan rastgele 5 sayı örneği verilmiştir.
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)
Bunu tek bir astarla da yapabilirsiniz:
[...((add, set) => add(set, add))((set, add) => set.size < 8 ? add(set.add(Math.floor(Math.random()*100) + 1), add) : set, new Set())]