কিভাবে একটি অ্যারের থেকে এলোমেলো উপাদান সংখ্যা পেতে?


103

আমি 'জাভাস্ক্রিপ্টের একটি অ্যারে থেকে এলোমেলোভাবে কীভাবে উপাদানগুলি অ্যাক্সেস করব' এ নিয়ে কাজ করছি। আমি এ সম্পর্কিত অনেক লিঙ্ক খুঁজে পেয়েছি। পছন্দ: জাভাস্ক্রিপ্ট অ্যারে থেকে এলোমেলো আইটেম পান

var item = items[Math.floor(Math.random()*items.length)];

তবে এটিতে আমরা অ্যারে থেকে কেবল একটি আইটেম বেছে নিতে পারি। আমরা যদি একাধিক উপাদান চাই তবে আমরা কীভাবে এটি অর্জন করতে পারি? অ্যারে থেকে আমরা কীভাবে একাধিক উপাদান পেতে পারি?


4
শুধু একাধিক বার এটি কার্যকর?
বার্গি

4
এই বিবৃতি থেকে আমরা এই কি করতে পারি ?? লুপ তৈরির সদৃশ।
শ্যাম দীক্ষিত

4
সঠিক বিবৃতি থেকে আপনি একাধিক উপাদান পেতে পারবেন না।
সাবাসতিয়েন

4
আহ, আপনার বলা উচিত ছিল যে আপনি কোনও সদৃশ চান না। তারপরে ও (1) এ ইউনিক এলোমেলো নম্বরগুলি পরীক্ষা করে দেখুন ? এবং আমার উত্তরটি সীমার মধ্যে অনন্য নম্বর উত্পন্ন করুন (0 - এক্স), সদৃশ প্রতিরোধের জন্য একটি ইতিহাস রেখে
বার্গি

4
আমি এখানে কিছু সমাধান পরীক্ষা করার জন্য একটি জেসফ্রু তৈরি করেছি। @ বার্গি সাধারণভাবে সেরা বলে মনে হচ্ছে, অন্যদিকে যদি অ্যারের থেকে অনেক উপাদানগুলির প্রয়োজন হয় তবে খনিটি আরও ভাল কাজ করে।jsperf.com/k-random-elements-from-array
টিবোস

উত্তর:


97

এই অ-ধ্বংসাত্মক চেষ্টা করুন (এবং দ্রুত ) ফাংশনটি ব্যবহার করে দেখুন:

function getRandom(arr, n) {
    var result = new Array(n),
        len = arr.length,
        taken = new Array(len);
    if (n > len)
        throw new RangeError("getRandom: more elements taken than available");
    while (n--) {
        var x = Math.floor(Math.random() * len);
        result[n] = arr[x in taken ? taken[x] : x];
        taken[x] = --len in taken ? taken[len] : len;
    }
    return result;
}

10
আরে মানুষ, আমি শুধু বলতে চেয়েছিলাম যে আমি এই অ্যালগরিদমের সৌন্দর্যের প্রশংসা করতে প্রায় 10 মিনিট ব্যয় করেছি।
প্রজিথ ইমানুয়েল

আমি যদি গতিতে চলি তবে পাইথনের প্রয়োগটি ব্যবহারের পরামর্শ দেব : jsperf.com/pick-random-elements-from-an-array
ডেরেক 朕

@ ডেরেক 朕 會 功夫 আহ, চালাক, প্রকৃতপক্ষে বড় পরিসরের ছোট ছোট নমুনাগুলির জন্য আরও ভাল কাজ করে। বিশেষত একটি ES6 ব্যবহার করে Set(যা '13: - / এ উপলব্ধ ছিল না)
বার্গি

@ অ্যালেক্সওহাইট প্রতিক্রিয়ার জন্য ধন্যবাদ, আমি বিশ্বাস করতে পারি না যে এই বাগটি বছরের পর বছর ধরে সবাইকে এড়িয়ে গিয়েছিল। স্থির। আপনার কোনও মন্তব্য পোস্ট করা উচিত ছিল, কোনও সম্পাদনার প্রস্তাব দেওয়া হয়নি।
বার্গি

4
@ সিবিদেব 420 হ্যাঁ, এটি কেবলমাত্র একটি (আংশিক) ফিশার-ইয়েটস বদল
বার্গি

187

মাত্র দুটি লাইন:

// Shuffle array
const shuffled = array.sort(() => 0.5 - Math.random());

// Get sub-array of first n elements after shuffled
let selected = shuffled.slice(0, n);

ডেমো :


22
খুব সুন্দর! একটি লাইনার অবশ্যই সম্ভব:let random = array.sort(() => .5 - Math.random()).slice(0,n)
ইউনিটরিও

4
প্রতিভা! বিল্ট-ইন কার্যকারিতাটি ব্যবহার করে মার্জিত, সংক্ষিপ্ত এবং সহজ, দ্রুত।
ভ্লাদ

35
এটি দুর্দান্ত, তবে এলোমেলোভাবে অনেক দূরে। প্রথম আইটেমটি শেষেরটির তুলনায় আরও অনেক সম্ভাবনা রয়েছে। এখানে কেন দেখুন: stackoverflow.com/a/18650169/1325646
pomber

এটি মূল অ্যারের ধরণের সংরক্ষণ করে না
আলমাথি

4
আশ্চর্য! আপনি যদি অ্যারেটি অক্ষত রাখতে চান তবে আপনি কেবল প্রথম লাইনে এইভাবে পরিবর্তন করতে পারবেন: কনস্ট শ্ফলেড = [... অ্যারে] s
ইয়ার লেভি

16

এখানে একটি-লাইনার অনন্য সমাধান রয়েছে

 array.sort(() => Math.random() - Math.random()).slice(0, n)

4
এটি কাজ করার সময় এটি বড় অ্যারেগুলির জন্যও ধীর হতে পারে।
ফিলিপ

এটি আপনাকে এমনকি বিতরণ করে না। দেখুন robweir.com/blog/2010/02/microsoft-random-browser-ballot.html
JasonWoof

12

.sampleপাইথন স্ট্যান্ডার্ড লাইব্রেরি থেকে পোর্টিং :

function sample(population, k){
    /*
        Chooses k unique random elements from a population sequence or set.

        Returns a new list containing elements from the population while
        leaving the original population unchanged.  The resulting list is
        in selection order so that all sub-slices will also be valid random
        samples.  This allows raffle winners (the sample) to be partitioned
        into grand prize and second place winners (the subslices).

        Members of the population need not be hashable or unique.  If the
        population contains repeats, then each occurrence is a possible
        selection in the sample.

        To choose a sample in a range of integers, use range as an argument.
        This is especially fast and space efficient for sampling from a
        large population:   sample(range(10000000), 60)

        Sampling without replacement entails tracking either potential
        selections (the pool) in a list or previous selections in a set.

        When the number of selections is small compared to the
        population, then tracking selections is efficient, requiring
        only a small set and an occasional reselection.  For
        a larger number of selections, the pool tracking method is
        preferred since the list takes less space than the
        set and it doesn't suffer from frequent reselections.
    */

    if(!Array.isArray(population))
        throw new TypeError("Population must be an array.");
    var n = population.length;
    if(k < 0 || k > n)
        throw new RangeError("Sample larger than population or is negative");

    var result = new Array(k);
    var setsize = 21;   // size of a small set minus size of an empty list

    if(k > 5)
        setsize += Math.pow(4, Math.ceil(Math.log(k * 3, 4)))

    if(n <= setsize){
        // An n-length list is smaller than a k-length set
        var pool = population.slice();
        for(var i = 0; i < k; i++){          // invariant:  non-selected at [0,n-i)
            var j = Math.random() * (n - i) | 0;
            result[i] = pool[j];
            pool[j] = pool[n - i - 1];       // move non-selected item into vacancy
        }
    }else{
        var selected = new Set();
        for(var i = 0; i < k; i++){
            var j = Math.random() * n | 0;
            while(selected.has(j)){
                j = Math.random() * n | 0;
            }
            selected.add(j);
            result[i] = population[j];
        }
    }

    return result;
}

বাস্তবায়ন Lib / random.py থেকে পোর্ট করা হয়েছে ।

মন্তব্য:

  • setsizeদক্ষতার জন্য পাইথনের বৈশিষ্ট্যের ভিত্তিতে সেট করা হয়েছে। যদিও এটি জাভাস্ক্রিপ্টের জন্য সামঞ্জস্য করা হয়নি, তবে অ্যালগরিদম এখনও প্রত্যাশা অনুযায়ী কাজ করবে।
  • এই পৃষ্ঠায় বর্ণিত আরও কিছু উত্তর অপব্যবহারের কারণে ইসমাস্ক্রিপ্টের স্পেসিফিকেশন অনুযায়ী নিরাপদ নয় Array.prototype.sort। এই অ্যালগরিদম অবশ্য সীমাবদ্ধ সময়ে শেষ করার গ্যারান্টিযুক্ত।
  • Setপ্রয়োগ করা হয়নি এমন পুরানো ব্রাউজারগুলির জন্য , সেটটি একটি দ্বারা প্রতিস্থাপন Arrayএবং .has(j)প্রতিস্থাপন করা যেতে পারে .indexOf(j) > -1

গৃহীত উত্তরের বিরুদ্ধে অভিনয়:


আমি নীচে এই কোডটির একটি অনুকূলিত সংস্করণ পোস্ট করেছি । আপনার পোস্টের দ্বিতীয় আলগোতে ভুল র্যান্ডম প্যারামিটারটিও সংশোধন করে। আমি আশ্চর্য হয়েছি যে কত লোক পূর্বের পক্ষপাতদুষ্ট সংস্করণটি উত্পাদনে ব্যবহার করছে, আশা করি সমালোচনামূলক কিছুই নয়।
ব্যবহারকারী

11

মূল অ্যারে পরিবর্তন না করে 5 টি এলোমেলো আইটেম পাওয়া:

const n = 5;
const sample = items
  .map(x => ({ x, r: Math.random() }))
  .sort((a, b) => a.r - b.r)
  .map(a => a.x)
  .slice(0, n);

(এটি বড় তালিকার জন্য ব্যবহার করবেন না)


আমরা কীভাবে এটি কাজ করে তার আরও ভাল ব্যাখ্যা করতে পারি?
কাসিম

10

একটি ফানসিওন তৈরি করুন যা এটি করে:

var getMeRandomElements = function(sourceArray, neededElements) {
    var result = [];
    for (var i = 0; i < neededElements; i++) {
        result.push(sourceArray[Math.floor(Math.random()*sourceArray.length)]);
    }
    return result;
}

সোর্স অ্যারেতে ফিরে আসার মতো পর্যাপ্ত উপাদান রয়েছে কিনা তাও আপনার পরীক্ষা করা উচিত। এবং যদি আপনি চান অনন্য উপাদানগুলি ফিরে আসে, আপনার উত্সআরে থেকে নির্বাচিত উপাদানটি সরিয়ে নেওয়া উচিত।


ভাল উত্তর! আমার উত্তরটি একবার দেখুন, আপনার কোডটি অনুলিপি করেছেন এবং "কেবলমাত্র অনন্য উপাদান" কার্যকারিতা যুক্ত করেছেন।
অশুভরিকো

4
এই ফাংশনটি sourceArrayএকাধিকবার একই উপাদানকে ফিরিয়ে দিতে পারে ।
সাম্পো

6

ES6 সিনট্যাক্স

const pickRandom = (arr,count) => {
  let _arr = [...arr];
  return[...Array(count)].map( ()=> _arr.splice(Math.floor(Math.random() * _arr.length), 1)[0] ); 
}

4

যদি আপনি পুনরাবৃত্তি ছাড়াই এলোমেলোভাবে অ্যারে থেকে আইটেমগুলি পেতে চান তবে আপনি নির্বাচিত আইটেমটি অ্যারে থেকে এটিকে সরাতে পারেন splice:

var items = [1, 2, 3, 4, 5];
var newItems = [];

for (var i = 0; i < 3; i++) {
  var idx = Math.floor(Math.random() * items.length);
  newItems.push(items[idx]);
  items.splice(idx, 1);
}

console.log(newItems);


4
বিবৃতিতে আইটেম.স্প্লাইস (আইডিএক্স, 1) আপনি কেন এই '1' ব্যবহার করেন? ভাঁজ ??
শ্যাম দীক্ষিত

4
শ্যাম দীক্ষিত অনুযায়ী MDN ডকুমেন্টেশন1 হয় deleteCountমুছে ফেলার জন্য পুরাতন অ্যারের উপাদানের সংখ্যা নির্দেশ করে। (ঘটনাচক্রে, আমি শেষ দুটি লাইন কমিয়ে দিয়েছি newItems.push(items.splice(idx, 1)[0]))।
কর্ট পিক

2
Array.prototype.getnkill = function() {
    var a = Math.floor(Math.random()*this.length);
    var dead = this[a];
    this.splice(a,1);
    return dead;
}

//.getnkill() removes element in the array 
//so if you like you can keep a copy of the array first:

//var original= items.slice(0); 


var item = items.getnkill();

var anotheritem = items.getnkill();

2

এখানে একটি সুন্দর টাইপিত সংস্করণ। এটি ব্যর্থ হয় না। যদি নমুনার আকার মূল অ্যারের দৈর্ঘ্যের চেয়ে বড় হয় তবে একটি বদলানো অ্যারে ফেরত দেয়।

function sampleArr<T>(arr: T[], size: number): T[] {
  const setOfIndexes = new Set<number>();
  while (setOfIndexes.size < size && setOfIndexes.size < arr.length) {
    setOfIndexes.add(randomIntFromInterval(0, arr.length - 1));
  }
  return Array.from(setOfIndexes.values()).map(i => arr[i]);
}

const randomIntFromInterval = (min: number, max: number): number =>
  Math.floor(Math.random() * (max - min + 1) + min);

2

লোডাশ ( https://lodash.com/ ) _.sampleএবং_.sampleSize

সংগ্রহ থেকে আকারের অবধি অনন্য কীগুলিতে এক বা এন এলোমেলো উপাদান পান।

_.sample([1, 2, 3, 4]);
// => 2

_.sampleSize([1, 2, 3], 2);
// => [3, 1]
 
_.sampleSize([1, 2, 3], 4);
// => [2, 3, 1]

কী _? এটি কোনও স্ট্যান্ডার্ড জাভাস্ক্রিপ্ট অবজেক্ট নয়।
ভ্যানোম

হাই @ ওয়ানোওম, এটি লোডাস লডাশ ডটকম
নোডেজ

1

সম্পাদনা : আপনি কেবল কয়েকটি উপাদান পেতে চাইলে এই সমাধানটি এখানে উপস্থাপিত অন্যদের তুলনায় ধীরে ধীরে (যা উত্স অ্যারেটি বিভক্ত করে তোলে)। এই দ্রষ্টব্যটির গতি কেবলমাত্র মূল অ্যারেতে থাকা উপাদানের সংখ্যার উপর নির্ভর করে, তবে বিভক্ত দ্রবণটির গতি আউটপুট অ্যারেতে প্রয়োজনীয় উপাদানের সংখ্যার উপর নির্ভর করে।

আপনি যদি অ-পুনরাবৃত্তি এলোমেলো উপাদান চান, আপনি আপনার অ্যারে পরিবর্তন করতে পারেন তারপর আপনি চান হিসাবে কেবল পেতে:

function shuffle(array) {
    var counter = array.length, temp, index;

    // While there are elements in the array
    while (counter--) {
        // Pick a random index
        index = (Math.random() * counter) | 0;

        // And swap the last element with it
        temp = array[counter];
        array[counter] = array[index];
        array[index] = temp;
    }

    return array;
}

var arr = [0,1,2,3,4,5,7,8,9];

var randoms = shuffle(arr.slice(0)); // array is cloned so it won't be destroyed
randoms.length = 4; // get 4 random elements

ডেমো: http://jsbin.com/UHUHuqi/1/edit

এখান থেকে তোলা ফাংশনটি: https://stackoverflow.com/a/6274398/1669279 9


এটি অ্যারে থেকে প্রয়োজনীয় এলোমেলো আইটেমগুলির শতাংশের উপর নির্ভর করে। যদি আপনি 10 টি উপাদান অ্যারে থেকে 9 এলোমেলো উপাদান চান তবে এটি একের পর এক 9 টি এলোমেলো উপাদান বের করার চেয়ে এলোমেলোভাবে দ্রুততর হবে। যদি এটির জন্য কার্যকর শতাংশটি 50% এর চেয়ে কম হয়, তবে ব্যবহারের ক্ষেত্রে খুব বেশি সমস্যা রয়েছে যেখানে এই সমাধানটি সবচেয়ে দ্রুত। অন্যথায় আমি স্বীকার করি যে এটি অকেজো :)।
টিবোস

আমি বোঝাতে চাইছি যে 9 টি উপাদান পরিবর্তন করা 10 টি উপাদানকে সাফ করার চেয়ে দ্রুত। বিটিডব্লু আমি আত্মবিশ্বাসী যে ওপি তার ইনপুট অ্যারেটি ধ্বংস করতে চায় না ...
বার্গি

আমি মনে করি না যে আমি বুঝতে পারি 9 টি উপাদান এলোমেলো করা কীভাবে এই সমস্যায় সহায়তা করে। আমি সচেতন যে আপনি যদি অর্ধেকেরও বেশি অ্যারে চান তবে আপনি এলোমেলো উপাদানগুলি স্লাইস আউট করতে পারবেন যতক্ষণ না আপনি যতক্ষণ না চান তার সাথে এলোমেলো অর্ডার পেতে ঝাঁকুনি দিন। আমি কি কিছু মিস করেছি? PS: স্থির অ্যারে ধ্বংস, ধন্যবাদ।
টিবোস

এটি "অর্ধেক" দিয়ে কিছু করার দরকার নেই। আপনি যে উপাদানগুলি ফিরে পেতে চান তার পক্ষে আপনাকে যতটা কাজ করা দরকার, আপনাকে কোনও বিন্দুতে পুরো অ্যারেটি ব্যবহার করার দরকার নেই। আপনার বর্তমান কোডটিতে O(n+k)(অ্যারেতে থাকা n উপাদানসমূহের একটি জটিলতা রয়েছে , আপনি তাদের মধ্যে কে চান) আপনার O(k)সম্ভাব্য (এবং অনুকূল) হতে পারে।
বার্গি

4
ঠিক আছে, আপনার কোডটির মতো আরও কিছু রয়েছে O(2n)যা আপনি O(n+k)যদি লুপটি পরিবর্তন করতে while (counter-- > len-k)এবং kএটিকে শেষ (প্রথমটির পরিবর্তে) উপাদানগুলি থেকে বের করে নিতে চান তবে তা হ্রাস পেতে পারে । প্রকৃতপক্ষে splice(i, 1)নেই O(1), তবে একটি O(k)সমাধান এখনও সম্ভব (আমার উত্তর দেখুন)। মহাশূন্য জটিলতা O(n+k)দুর্ভাগ্যক্রমে O(2k)থাকলেও বিরল অ্যারে প্রয়োগের উপর নির্ভর করে হয়ে উঠতে পারে ।
বার্গি

1

এই ধরণের সমস্যা সমাধানের জন্য আমার একটি ফাংশন প্রয়োজন তাই আমি এটি এখানে ভাগ করছি।

    const getRandomItem = function(arr) {
        return arr[Math.floor(Math.random() * arr.length)];
    }

    // original array
    let arr = [4, 3, 1, 6, 9, 8, 5];

    // number of random elements to get from arr
    let n = 4;

    let count = 0;
    // new array to push random item in
    let randomItems = []
    do {
        let item = getRandomItem(arr);
        randomItems.push(item);
        // update the original array and remove the recently pushed item
        arr.splice(arr.indexOf(item), 1);
        count++;
    } while(count < n);

    console.log(randomItems);
    console.log(arr);

দ্রষ্টব্য: তবে যদি n = arr.lengthআপনি মূলত অ্যারে পরিবর্তন করে থাকেন arrএবং randomItemsফেরত দেওয়া সেই অ্যারেটি ফিরিয়ে দেন।

ডেমো


1

এই উত্তরে আমি আপনার সাথে এই পরীক্ষাটি ভাগ করতে চাই যে আমাকে সেরা পদ্ধতিটি জানতে হবে যা সমস্ত উপাদানকে এলোমেলোভাবে সাববারে করার সমান সুযোগ দেয়।

পদ্ধতি 01

array.sort(() => Math.random() - Math.random()).slice(0, n)

এই পদ্ধতিটি ব্যবহার করে কিছু উপাদানগুলির অন্যদের সাথে তুলনা করার সম্ভাবনা বেশি থাকে।

calculateProbability = function(number=0 ,iterations=10000,arraySize=100) { 
let occ = 0 
for (let index = 0; index < iterations; index++) {
   const myArray= Array.from(Array(arraySize).keys()) //=> [0, 1, 2, 3, 4, ... arraySize]
   
  /** Wrong Method */
    const arr = myArray.sort(function() {
     return val= .5 - Math.random();
      });
     
  if(arr[0]===number) {
    occ ++
    }

    
}

console.log("Probability of ",number, " = ",occ*100 /iterations,"%")

}

calculateProbability(0)
calculateProbability(0)
calculateProbability(0)
calculateProbability(50)
calculateProbability(50)
calculateProbability(50)
calculateProbability(25)
calculateProbability(25)
calculateProbability(25)

পদ্ধতি 2

এই পদ্ধতিটি ব্যবহার করে উপাদানগুলির একই সম্ভাবনা রয়েছে:

 const arr = myArray
      .map((a) => ({sort: Math.random(), value: a}))
      .sort((a, b) => a.sort - b.sort)
      .map((a) => a.value)

calculateProbability = function(number=0 ,iterations=10000,arraySize=100) { 
let occ = 0 
for (let index = 0; index < iterations; index++) {
   const myArray= Array.from(Array(arraySize).keys()) //=> [0, 1, 2, 3, 4, ... arraySize]
   

  /** Correct Method */
  const arr = myArray
  .map((a) => ({sort: Math.random(), value: a}))
  .sort((a, b) => a.sort - b.sort)
  .map((a) => a.value)
    
  if(arr[0]===number) {
    occ ++
    }

    
}

console.log("Probability of ",number, " = ",occ*100 /iterations,"%")

}

calculateProbability(0)
calculateProbability(0)
calculateProbability(0)
calculateProbability(50)
calculateProbability(50)
calculateProbability(50)
calculateProbability(25)
calculateProbability(25)
calculateProbability(25)

সঠিক উত্তরটি নিম্নলিখিত লিঙ্কটিতে পোস্ট করা হয়েছে: https://stackoverflow.com/a/46545530/3811640


1

এখানে একজন অপ্টিমাইজ সংস্করণ কোড @Derek দ্বারা পাইথন থেকে বৈশিষ্ট্যসমূহ নিয়ে আসা, এটা দ্রুততম সম্ভব অ্যালগরিদম যদি আপনি এটি দিয়ে যেতে পারেন যে যোগ ধ্বংসাত্মক (ইন-স্থান) বিকল্প। অন্যথায় এটি হয় একটি সম্পূর্ণ অনুলিপি তৈরি করে বা, একটি বড় অ্যারে থেকে অনুরোধ করা আইটেমের সংখ্যক সংখ্যার জন্য, একটি নির্বাচন-ভিত্তিক অ্যালগরিদমে স্যুইচ করে।

// Chooses k unique random elements from pool.
function sample(pool, k, destructive) {
    var n = pool.length;

    if (k < 0 || k > n)
        throw new RangeError("Sample larger than population or is negative");

    if (destructive || n <= (k <= 5 ? 21 : 21 + Math.pow(4, Math.ceil(Math.log(k*3, 4))))) {
        if (!destructive)
            pool = Array.prototype.slice.call(pool);
        for (var i = 0; i < k; i++) { // invariant: non-selected at [i,n)
            var j = i + Math.random() * (n - i) | 0;
            var x = pool[i];
            pool[i] = pool[j];
            pool[j] = x;
        }
        pool.length = k; // truncate
        return pool;
    } else {
        var selected = new Set();
        while (selected.add(Math.random() * n | 0).size < k) {}
        return Array.prototype.map.call(selected, i => population[i]);
    }
}

ডেরেকের বাস্তবায়নের তুলনায়, ক্রোমটিতে কিছুটা ধীর হয়ে যাওয়ার পরে প্রথম অ্যালগরিদম ফায়ারফক্সে আরও দ্রুততর হয়, যদিও এখন এটির ধ্বংসাত্মক বিকল্প রয়েছে - সর্বাধিক পারফরম্যান্ট। দ্বিতীয় অ্যালগরিদম কেবল 5-15% দ্রুত। আমি কোনও কংক্রিট নম্বর না দেওয়ার চেষ্টা করি যেহেতু এগুলি কে এবং এন এর উপর নির্ভর করে পরিবর্তিত হয় এবং ভবিষ্যতে নতুন ব্রাউজার সংস্করণগুলির সাথে কিছু বোঝায় না।

আলগোরিদিমগুলির মধ্যে যে শব্দটি তৈরি হয় তা পাইথন কোড থেকে উদ্ভূত। আমি এটি যেমনটি রেখেছি তেমনি এটি কখনও কখনও ধীরে ধীরে নির্বাচন করে। এটি জেএসের জন্য অনুকূলিত করা উচিত, তবে কর্নার কেসগুলির পারফরম্যান্স ব্রাউজার- এবং তাদের সংস্করণ নির্ভর- উদাহরণস্বরূপ, আপনি যখন 1000 বা 1050 এর মধ্যে 20 টি নির্বাচন করার চেষ্টা করবেন, সে অনুযায়ী এটি প্রথম বা দ্বিতীয় অ্যালগরিদমে স্যুইচ করবে। এক্ষেত্রে প্রথমটি ক্রোম ৮০ এ দ্বিতীয়টির চেয়ে ২x দ্রুত এবং ফায়ারফক্স 74৪ এ 3x ধীর গতিতে চলে।


log(k*3, 4)জেএসের baseযুক্তি না থাকায় একটি ত্রুটি রয়েছে । হওয়া উচিতlog(k*3)/log(4)
বিচ্ছুরিত

এছাড়াও, আপনি যে অংশটি পুনরায় ব্যবহার poolকরেছেন সেই অংশে আমি একটি খারাপ দিক দেখছি result। যেহেতু আপনি কেটে ফেলেছেন poolএটি আর নমুনা তৈরির উত্স হিসাবে ব্যবহার করা যাবে না এবং পরের বার আপনি যখন ব্যবহার করবেন তখন sampleআপনাকে poolআবার কোনও উত্স থেকে পুনরায় তৈরি করতে হবে । ডেরেকের বাস্তবায়ন কেবল পুলটি বদল করে, তাই পুনরায় পুনরায় চেষ্টা না করে স্যাম্পলিংয়ের জন্য একেবারে পুনরায় ব্যবহার করা যেতে পারে। এবং আমি বিশ্বাস করি এটি সবচেয়ে ঘন ঘন ব্যবহারের ক্ষেত্রে।
বিচ্ছুরিত

1

2020
অ ধ্বংসাত্মক কার্যকরী প্রোগ্রামিং শৈলী, একটি পরিবর্তনীয় প্রসঙ্গে কাজ করা।

const _randomslice = (ar, size) => {
  let new_ar = [...ar];
  new_ar.splice(Math.floor(Math.random()*ar.length),1);
  return ar.length <= (size+1) ? new_ar : _randomslice(new_ar, size);
}


console.log(_randomslice([1,2,3,4,5],2));


আমি বুঝতে পারি যে ফাংশনটি কোনও উত্স অ্যারে থেকে সমস্ত সম্ভাব্য এলোমেলো অ্যারে তৈরি করে না। অন্য পৃথিবীতে, ফলাফলটি যতটা এলোমেলো হয় না তেমন ... উন্নতির কোনও ধারণা?
ম্যাম সাবসটিয়েন

_shuffleফাংশন কোথায় ?
ভ্যানোম

0

এটি যথেষ্ট পরিমাণে পাওয়ার পরে একে একে এসআরসিআরএর থেকে এলোমেলো উপাদানগুলি বের করে বা এসক্রিআরিতে আর কোনও উপাদান বের করার জন্য অবশিষ্ট নেই। দ্রুত এবং নির্ভরযোগ্য।

function getNRandomValuesFromArray(srcArr, n) {
    // making copy to do not affect original srcArray
    srcArr = srcArr.slice();
    resultArr = [];
    // while srcArray isn't empty AND we didn't enough random elements
    while (srcArr.length && resultArr.length < n) {
        // remove one element from random position and add this element to the result array
        resultArr = resultArr.concat( // merge arrays
            srcArr.splice( // extract one random element
                Math.floor(Math.random() * srcArr.length),
                1
            )
        );
    }

    return resultArr;
}


তাই আপনাকে স্বাগতম! উত্তর পোস্ট করার সময়, আপনার কোডটি কীভাবে কাজ করে এবং / বা এটি ওপির সমস্যা সমাধান করে কীভাবে তা উল্লেখ করা গুরুত্বপূর্ণ :)
জোয়েল

0

2019

এটি Laurynas Mališauskas জবাব হিসাবে একই , উপাদানগুলি অনন্য (কোনও নকল নেই)।

var getMeRandomElements = function(sourceArray, neededElements) {
    var result = [];
    for (var i = 0; i < neededElements; i++) {
    var index = Math.floor(Math.random() * sourceArray.length);
        result.push(sourceArray[index]);
        sourceArray.splice(index, 1);
    }
    return result;
}

এখন আসল প্রশ্নের উত্তর দিতে "jQuery দ্বারা একাধিক এলোমেলো উপাদান কীভাবে পাবেন", আপনি এখানে যান:

var getMeRandomElements = function(sourceArray, neededElements) {
    var result = [];
    for (var i = 0; i < neededElements; i++) {
    var index = Math.floor(Math.random() * sourceArray.length);
        result.push(sourceArray[index]);
        sourceArray.splice(index, 1);
    }
    return result;
}

var $set = $('.someClass');// <<<<< change this please

var allIndexes = [];
for(var i = 0; i < $set.length; ++i) {
    allIndexes.push(i);
}

var totalRandom = 4;// <<<<< change this please
var randomIndexes = getMeRandomElements(allIndexes, totalRandom);

var $randomElements = null;
for(var i = 0; i < randomIndexes.length; ++i) {
    var randomIndex = randomIndexes[i];
    if($randomElements === null) {
        $randomElements = $set.eq(randomIndex);
    } else {
        $randomElements.add($set.eq(randomIndex));
    }
}

// $randomElements is ready
$randomElements.css('backgroundColor', 'red');

0

আমি এখানে একটি ফাংশন ব্যবহার করছি যা আপনাকে সহজেই প্রতিস্থাপনের সাথে বা ছাড়াই কোনও অ্যারে নমুনা করতে দেয়:

  // Returns a random sample (either with or without replacement) from an array
  const randomSample = (arr, k, withReplacement = false) => {
    let sample;
    if (withReplacement === true) {  // sample with replacement
      sample = Array.from({length: k}, () => arr[Math.floor(Math.random() *  arr.length)]);
    } else { // sample without replacement
      if (k > arr.length) {
        throw new RangeError('Sample size must be less than or equal to array length         when sampling without replacement.')
      }
      sample = arr.map(a => [a, Math.random()]).sort((a, b) => {
        return a[1] < b[1] ? -1 : 1;}).slice(0, k).map(a => a[0]); 
      };
    return sample;
  };

এটি ব্যবহার করা সহজ:

প্রতিস্থাপন ছাড়াই (ডিফল্ট আচরণ)

randomSample([1, 2, 3], 2) ফিরে আসতে পারে [2, 1]

প্রতিস্থাপন সহ

randomSample([1, 2, 3, 4, 5, 6], 4) ফিরে আসতে পারে [2, 3, 3, 2]


0
var getRandomElements = function(sourceArray, requiredLength) {
    var result = [];
    while(result.length<requiredLength){
        random = Math.floor(Math.random()*sourceArray.length);
        if(result.indexOf(sourceArray[random])==-1){
            result.push(sourceArray[random]);
        }
    }
    return result;
}

0

আমি বিশ্বাস করতে পারি না যে কেউ এই পদ্ধতিটি উল্লেখ করেনি, বেশ পরিষ্কার এবং সরাসরি এগিয়ে।

const getRnd = (a, n) => new Array(n).fill(null).map(() => a[Math.floor(Math.random() * a.length)]);

আপনি নিশ্চিত করছেন না যে দুটি আইটেম পুনরাবৃত্তি না হয়।
ভ্যালারি

-2

এখানে সর্বাধিক সঠিক উত্তর এবং এটি আপনাকে এলোমেলো + অনন্য উপাদান দেয়।

function randomize(array, n)
{
    var final = [];
    array = array.filter(function(elem, index, self) {
        return index == self.indexOf(elem);
    }).sort(function() { return 0.5 - Math.random() });

    var len = array.length,
    n = n > len ? len : n;

    for(var i = 0; i < n; i ++)
    {
        final[i] = array[i];
    }

    return final;
}

// randomize([1,2,3,4,5,3,2], 4);
// Result: [1, 2, 3, 5] // Something like this

এটির মধ্যে এলোমেলোকরণের সাথে অদ্ভুত কিছু চলছে - 9 টির মধ্যে 6 টির মধ্যে আমার একই ফলাফল (8 এর এন এবং 148 এর অ্যারের আকার সহ) প্রদর্শিত হয়েছিল। আপনি একটি এ স্যুইচিং সম্পর্কে চিন্তা করতে পারেন ফিশার-ইয়েটস পদ্ধতিতে ; এটি আমি করেছি এবং এখন আরও ভাল কাজ করে।
অ্যাসেটনিওপ

এটি চতুর্ভুজ সময় নেয় কারণ এটি একটি খারাপ স্বতন্ত্রতা পরীক্ষা করে এবং প্রতিটি আইটেম নির্বাচন করার সমান সুযোগ পায় না কারণ এটি এলোমেলো তুলনা করে সাজানো।
রাই-

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.