मैं जावास्क्रिप्ट का उपयोग करके 1 और 100 के बीच कुछ अद्वितीय यादृच्छिक संख्या कैसे उत्पन्न कर सकता हूं ?
मैं जावास्क्रिप्ट का उपयोग करके 1 और 100 के बीच कुछ अद्वितीय यादृच्छिक संख्या कैसे उत्पन्न कर सकता हूं ?
जवाबों:
उदाहरण के लिए: 8 अद्वितीय यादृच्छिक संख्याओं को उत्पन्न करने और उन्हें एक सरणी में संग्रहीत करने के लिए, आप बस ऐसा कर सकते हैं:
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)
। अगर the Math.random()
गलती से 0 वापस आता है, तो Math.ceil(0)
0 भी है, हालांकि मौका कम है।
randlines file | head -10
।
100 नंबरों का क्रमचय उत्पन्न करें और फिर क्रमबद्ध रूप से चुनें।
उपयोग नुथ घसीटना (उर्फ फिशर-येट्स फेरबदल) एल्गोरिथ्म ।
जावास्क्रिप्ट:
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;
}
}
संपादित करें :
बेहतर कोड:
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);
}
संभावित समस्या:
मान लीजिए कि हमारे पास 100 नंबरों की सरणी है {उदा। [1,2,3 ... 100]} और हम 8 स्वैप के बाद स्वैप करना बंद कर देते हैं; तब अधिकांश बार सरणी {1,2,3,76,5,6,7,8, ... की संख्या की तरह दिखाई देगी, यहां फेरबदल किया जाएगा ... 10}।
क्योंकि हर संख्या को 1/100 तो प्रायिकता के साथ स्वैप किया जाएगा। स्वैपिंग के पहले 8 नंबर 8/100 है जबकि प्रोब। अन्य 92 की अदला-बदली 92/100 है।
लेकिन अगर हम पूर्ण सरणी के लिए एल्गोरिथ्म चलाते हैं तो हमें यकीन है कि (लगभग) हर प्रविष्टि को स्वैप किया जाता है।
अन्यथा हम एक सवाल का सामना करते हैं: कौन से 8 नंबर चुनने के लिए?
सेट का उपयोग करके आधुनिक जेएस समाधान (और औसत स्थिति ओ (एन))
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
जेएस में खोजने के लिए बहुत अच्छा ! हालांकि, यह समाधान तब तक अनावश्यक पीढ़ी की संख्या का कारण नहीं बनेगा जब तक कि एक विशिष्टता की आवश्यकता फिट नहीं होती है, खासकर अंतिम पुनरावृत्तियों में, यदि 8 100 के करीब था? इस प्रकार मुझे लगता है कि मैं sort
नीचे के साथ भी सुरुचिपूर्ण जवाब पसंद करता हूं ।
यदि आप किसी लाइब्रेरी से बचना चाहते हैं, तो उपरोक्त तकनीकें अच्छी हैं, लेकिन अगर आप लाइब्रेरी से ठीक हैं, तो मैं आपको जावास्क्रिप्ट में यादृच्छिक सामान बनाने के लिए संभावना की जाँच करने का सुझाव दूंगा ।
विशेष रूप से अपने प्रश्न को हल करने के लिए, संभावना का उपयोग करना जितना आसान है:
// 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>
अस्वीकरण, चांस के लेखक के रूप में, मैं थोड़ा पक्षपाती हूं;)
var codes = chance.unique(chance.string, 8)
यदि आपको किसी विशेष वर्ण पूल से खींचे गए कोड की आवश्यकता है, तो आप इसे इस तरह निर्दिष्ट कर सकते हैं: chance.unique(chance.string, 8, {pool: "abcd1234"})
जहाँ abcd1234 आप पूल में कोई भी वर्ण चाहें। देखें chancejs.com/#string
chance.string({ length: 8 })
और यदि आप केवल कुछ पात्रों को उस तार में प्रदर्शित करना चाहते हैं, chance.string({ pool: 'abcd1234', length: 8 })
जो कि abcd1234 के अक्षरों से यादृच्छिक 8 वर्ण स्ट्रिंग लौटाएगा, इसलिए उदाहरण के लिए "2c2c44bc" या "331141cc"
किसी भी लंबे और अविश्वसनीय फेरबदल से बचने के लिए, मैं निम्नलिखित कार्य करूंगा ...
वोइला - कोई दोहराया संख्या।
अगर कोई दिलचस्पी रखता है तो मैं बाद में कुछ वास्तविक कोड पोस्ट कर सकता हूं।
संपादित करें: यह शायद मुझ में प्रतिस्पर्धात्मक लकीर है, लेकिन @Alsciende द्वारा पोस्ट को देखने के बाद, मैं उस कोड को पोस्ट करने का विरोध नहीं कर सका, जिसका मैंने वादा किया था।
<!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>
एक अन्य तरीका यह है कि आरोही संख्याओं के साथ 100 आइटम सरणी उत्पन्न करें और इसे यादृच्छिक रूप से सॉर्ट करें। यह वास्तव में वास्तव में छोटी और (मेरी राय में) सरल स्निपेट की ओर जाता है।
const numbers = Array(100).fill().map((_, index) => index + 1);
numbers.sort(() => Math.random() - 0.5);
console.log(numbers.slice(0, 8));
sort
इसे अच्छी तरह से लागू किया गया हो, जो मुझे यकीन है कि यह है)।
मैं यह करूँगा:
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;
यह एक बहुत ही सामान्य कार्य है जो मैंने एक सरणी के लिए यादृच्छिक अद्वितीय / गैर-अद्वितीय पूर्णांक बनाने के लिए लिखा है। इस उत्तर के लिए इस परिदृश्य में अंतिम पैरामीटर को सही मान लें।
/* 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;
}
यहाँ 'tempObj' एक बहुत ही उपयोगी obj है क्योंकि उत्पन्न हर यादृच्छिक संख्या सीधे इस tempObj में जाँच करेगी यदि वह कुंजी पहले से मौजूद है, यदि नहीं, तो हम i को एक से कम करते हैं क्योंकि हमें 1 अतिरिक्त रन की आवश्यकता है क्योंकि वर्तमान यादृच्छिक संख्या पहले से मौजूद है ।
अपने मामले में, निम्नलिखित चलाएँ
_arrayRandom(8, 1, 100, true);
बस इतना ही।
min = (min) ? min : 1,
हमेशा वापस आएगी 1. (इसलिए 0 का चयन कभी नहीं किया जाएगा)
1 से 100 तक की संख्या को फेरबदल करना सही बुनियादी रणनीति है, लेकिन अगर आपको केवल 8 फेरबदल संख्याओं की आवश्यकता है, तो सभी 100 संख्याओं को फेरबदल करने की कोई आवश्यकता नहीं है।
मैं जावास्क्रिप्ट को बहुत अच्छी तरह से नहीं जानता, लेकिन मेरा मानना है कि जल्दी से 100 नल की एक सरणी बनाना आसान है। फिर, 8 राउंड के लिए, आप 99 + के माध्यम से n + 1 से यादृच्छिक रूप से चयनित तत्व के साथ सरणी का n तत्व (n 0 पर शुरू) स्वैप करते हैं, बेशक, किसी भी तत्व को अभी तक आबादी नहीं हुई है जिसका मतलब है कि तत्व वास्तव में होगा मूल सूचकांक प्लस 1, ताकि कारक में तुच्छ हो। जब आप 8 राउंड के साथ किया जाता है, तो आपके सरणी के पहले 8 तत्वों में आपके 8 फेरबदल नंबर होंगे।
मशीन पर्मर के रूप में एक ही क्रमपरिवर्तन एल्गोरिदम, लेकिन एक प्रोटोटाइप कार्यान्वयन के साथ। बड़ी संख्या में पिक्स के लिए बेहतर अनुकूल। यदि उपलब्ध हो तो js 1.7 विनाशकारी असाइनमेंट का उपयोग करता है।
// 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);
संपादित करें: बेलुगाब के उत्तर के आधार पर, एक अन्य प्रस्ताव, जो छोटी संख्या में अचार के लिए बेहतर है। विशिष्टता की गारंटी देने के लिए, हम एरे से उठाए गए नंबरों को हटा देते हैं।
// 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);
इस तरह के छेद के साथ सरणियों के लिए [,2,,4,,6,7,,]
क्योंकि मेरी समस्या इन छेदों को भरने के लिए थी। इसलिए मैंने अपनी आवश्यकता के अनुसार इसे संशोधित किया :)
निम्नलिखित संशोधित समाधान मेरे लिए काम किया :)
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
सबसे अच्छा पहले वाला उत्तर इसके द्वारा दिया गया उत्तर है sje397
। आपको जितने अच्छे रैंडम नंबर मिलेंगे, उतने जल्दी मिलेंगे।
मेरा समाधान उसके समाधान के समान है। हालांकि, कभी-कभी आप यादृच्छिक क्रम में यादृच्छिक संख्या चाहते हैं, और यही कारण है कि मैंने एक उत्तर पोस्ट करने का फैसला किया है। इसके अलावा, मैं एक सामान्य फ़ंक्शन प्रदान करता हूं।
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));
यहाँ मेरा ES6 संस्करण है जिसे मैंने एक साथ सिल दिया था। मुझे यकीन है कि यह थोड़ा अधिक समेकित हो सकता है।
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);
एक हैश टेबल के रूप में ऑब्जेक्ट गुणों का उपयोग करने के बारे में कैसे ? इस तरह आपका सबसे अच्छा परिदृश्य केवल 8 बार यादृच्छिक करना है। यह तभी प्रभावी होगा जब आप संख्याओं का एक छोटा हिस्सा चाहते हैं। यह फिशर-येट्स की तुलना में बहुत कम स्मृति गहन है क्योंकि आपको किसी सरणी के लिए स्थान आवंटित करने की आवश्यकता नहीं है।
var ht={}, i=rands=8;
while ( i>0 || keys(ht).length<rands) ht[Math.ceil(Math.random()*100)]=i--;
alert(keys(ht));
मुझे तब पता चला कि Object.keys (obj) एक ECMAScript 5 फीचर है, इसलिए अभी इनरनेट पर बहुत बेकार है। डर नहीं, क्योंकि मैंने इसे इस तरह से एक कुंजी फ़ंक्शन जोड़कर ECMAScript 3 संगत बनाया।
if (typeof keys == "undefined")
{
var keys = function(obj)
{
props=[];
for (k in ht) if (ht.hasOwnProperty(k)) props.push(k);
return props;
}
}
यदि आपको और अधिक अद्वितीय चाहिए तो आपको एक सरणी (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;
}
उपरोक्त कोड अधिक तेज़ है:
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, 90 83, 44, 43, 47, 7, 53]
जावास्क्रिप्ट 1.6 इंडेक्सऑफ फ़ंक्शन के साथ एक ही कोड का दूसरा बेहतर संस्करण (स्वीकृत उत्तर) जोड़ना। हर बार जब आप डुप्लिकेट की जाँच कर रहे हों तो पूरे ऐरो को लूप करने की आवश्यकता नहीं है।
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;
}
जावास्क्रिप्ट का पुराना संस्करण अभी भी शीर्ष पर संस्करण का उपयोग कर सकता है
पुनश्च: विकी को एक अद्यतन का सुझाव देने की कोशिश की गई लेकिन इसे अस्वीकार कर दिया गया। मुझे अभी भी लगता है कि यह दूसरों के लिए उपयोगी हो सकता है।
यह मेरा व्यक्तिगत समाधान है:
<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>
यह यादृच्छिक रूप से 8 अद्वितीय सरणी मान (0 और 7 के बीच) उत्पन्न करता है, फिर एक अलर्ट बॉक्स का उपयोग करके उन्हें प्रदर्शित करता है।
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;
}
मुझे लगता है कि यह विधि अधिकांश उत्तरों में दी गई विधियों से भिन्न है, इसलिए मैंने सोचा कि मैं यहां एक उत्तर जोड़ सकता हूं (हालांकि प्रश्न 4 साल पहले पूछा गया था)।
हम 100 यादृच्छिक संख्याएँ उत्पन्न करते हैं, और उनमें से प्रत्येक को 1 से 100 तक की संख्याओं के साथ टैग करते हैं। फिर हम इन टैग किए गए यादृच्छिक नंबरों को क्रमबद्ध करते हैं, और टैग बेतरतीब ढंग से बदल जाते हैं। वैकल्पिक रूप से, इस प्रश्न में आवश्यकतानुसार, कोई टैग किए गए यादृच्छिक संख्याओं के शीर्ष 8 को खोजने के साथ दूर कर सकता है। शीर्ष 8 आइटम ढूँढना पूरे सरणी को छाँटने से सस्ता है।
यहां ध्यान देना चाहिए, कि छंटाई एल्गोरिथ्म इस एल्गोरिथ्म को प्रभावित करता है। यदि उपयोग किया गया छँटाई एल्गोरिथ्म स्थिर है, तो छोटी संख्या के पक्ष में थोड़ा पूर्वाग्रह है। आदर्श रूप से, हम चाहते हैं कि छँटाई एल्गोरिथ्म अस्थिर हो और स्थिरता (या अस्थिरता) के प्रति पूरी तरह से समान संभावना वितरण के साथ उत्तर देने के लिए भी पक्षपाती न हो।
यह 20 अंक तक की यादृच्छिक संख्या को उत्पन्न करने से निपट सकता है
जे एस
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);
यह समाधान हैश का उपयोग करता है जो कि सरणी में रहता है, तो जाँच करने की तुलना में अधिक प्रदर्शन करने वाला ओ (1) है। इसकी अतिरिक्त सुरक्षित जाँच भी है। आशा करता हूँ की ये काम करेगा।
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))
एक जनरेटर के रूप में इसे लागू करने के साथ काम करने के लिए यह बहुत अच्छा बनाता है। ध्यान दें, यह कार्यान्वयन उन लोगों से अलग है जिनके लिए पहले पूरे इनपुट सरणी को फेरबदल करने की आवश्यकता होती है।
यह
sample
फ़ंक्शन आलसी तरीके से काम करता है, जो आपको मांगने वाले आइटमों के प्रति पुनरावृत्ति के लिए 1 यादृच्छिक आइटमN
देता है। यह अच्छा है क्योंकि यदि आप 1000 की सूची से केवल 3 आइटम चाहते हैं , तो आपको पहले सभी 1000 आइटमों को स्पर्श करने की आवश्यकता नहीं है।
// 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
ऐसे तरीके से लागू करने का विकल्प चुना जो इनपुट सरणी को म्यूट नहीं करता है, लेकिन आप आसानी से यह तर्क दे सकते हैं कि परिवर्तनशील कार्यान्वयन अनुकूल है।
उदाहरण के लिए, shuffle
फ़ंक्शन मूल इनपुट सरणी को म्यूट करना चाह सकता है। या आप हर बार इनपुट को अपडेट करते हुए एक ही इनपुट से कई बार नमूना लेना चाह सकते हैं।
// 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
सरणी इनपुट उत्परिवर्तन के कारण अब शुद्ध कार्य नहीं है , लेकिन कुछ परिस्थितियों में (ऊपर प्रदर्शित) यह अधिक समझ में आ सकता है।
एक और कारण मैंने एक फ़ंक्शन के बजाय एक जनरेटर चुना जो सिर्फ एक सरणी देता है क्योंकि आप कुछ विशिष्ट स्थिति तक नमूना जारी रखना चाह सकते हैं।
शायद मैं 1,000,000 यादृच्छिक संख्याओं की सूची से पहला अभाज्य अंक चाहता हूं।
क्योंकि हम एक जनरेटर के साथ काम कर रहे हैं, यह कार्य तुच्छ है
const randomPrimeNumber = listOfNumbers => {
for (let x of sample(Infinity) (listOfNumbers)) {
if (isPrime(x))
return x;
}
return NaN;
}
यह एक समय में लगातार 1 यादृच्छिक संख्या का नमूना लेगा, x
यह जांचें कि क्या यह प्रमुख है, तो x
यदि यह है तो वापस लौटें । यदि कोई प्राइम पाए जाने से पहले संख्याओं की सूची समाप्त हो जाती है, NaN
तो वापस कर दी जाती है।
ध्यान दें:
यह उत्तर मूल रूप से एक और प्रश्न पर साझा किया गया था जिसे इस एक के डुप्लिकेट के रूप में बंद कर दिया गया था। क्योंकि यह यहां प्रदान किए गए अन्य समाधानों से बहुत अलग है, मैंने इसे यहां भी साझा करने का निर्णय लिया है
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 का उपयोग करना Set
आपका सबसे तेज विकल्प है। यहां एक अद्वितीय यादृच्छिक प्राप्त करने के लिए एक सामान्य कार्य है जो कॉलबैक जनरेटर का उपयोग करता है। अब यह तेज और पुन: प्रयोज्य है ।
// 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))
यह फिशर येट्स / डर्स्टनफेल्ड शफल का कार्यान्वयन है , लेकिन एक सरणी के वास्तविक निर्माण के बिना इस प्रकार अंतरिक्ष जटिलता या स्मृति को कम करने की आवश्यकता होती है, जब उपलब्ध तत्वों की संख्या की तुलना में पिक आकार छोटा होता है।
100 से 8 नंबर लेने के लिए, 100 तत्वों की एक सरणी बनाना आवश्यक नहीं है।
मान लिया जाता है कि एक सरणी बनाई गई है,
rnd
1 से 100 तक यादृच्छिक संख्या ( ) प्राप्त करें rnd
यदि कोई सरणी नहीं बनाई गई है, तो वास्तविक स्वैप किए गए पदों को याद रखने के लिए ए हैशपॉप का उपयोग किया जा सकता है। जब उत्पन्न दूसरी यादृच्छिक संख्या पहले से उत्पन्न संख्याओं में से एक के बराबर होती है, तो मानचित्र वास्तविक मूल्य के बजाय उस स्थिति में वर्तमान मूल्य प्रदान करता है।
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 से 100 की सीमा (0 और 100 दोनों शामिल) से बिना किसी दोहराव के लिए लिए गए यादृच्छिक 5 नंबरों का एक उदाहरण है।
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)
आप इसे इस तरह से एक लाइनर के साथ भी कर सकते हैं:
[...((add, set) => add(set, add))((set, add) => set.size < 8 ? add(set.add(Math.floor(Math.random()*100) + 1), add) : set, new Set())]