Wie bekomme ich eine Anzahl von zufälligen Elementen aus einem Array?

95

Ich arbeite daran, wie man zufällig aus einem Array in Javascript auf Elemente zugreift. Ich habe diesbezüglich viele Links gefunden. Wie: Holen Sie sich zufällige Elemente aus dem JavaScript-Array

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

Dabei können wir jedoch nur ein Element aus dem Array auswählen. Wenn wir mehr als ein Element wollen, wie können wir dies erreichen? Wie können wir mehr als ein Element aus einem Array erhalten?

Shyam Dixit
quelle
5
Einfach mehrmals ausführen?
Bergi
2
Können wir aus dieser Aussage das machen? Schleife, die Duplikate erzeugt.
Shyam Dixit
1
Aus dieser genauen Aussage können Sie nicht mehr als ein Element erhalten.
Sébastien
1
Ah, du hättest sagen sollen, dass du keine Duplikate willst. Dann überprüfen Sie eindeutige Zufallszahlen in O (1)? und meine Antwort unter Generiere eine eindeutige Nummer innerhalb des Bereichs (0 - X), wobei ein Verlauf geführt wird, um Duplikate zu vermeiden
Bergi
1
Ich habe einen JsPerf erstellt, um einige der Lösungen hier zu testen. @ Bergi's scheint im Allgemeinen das Beste zu sein, während meins besser funktioniert, wenn Sie viele Elemente aus dem Array benötigen. jsperf.com/k-random-elements-from-array
Tibos

Antworten:

93

Probieren Sie diese zerstörungsfreie (und schnelle ) Funktion aus:

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;
}
Bergi
quelle
6
Hey Mann, ich wollte nur sagen, dass ich ungefähr zehn Minuten damit verbracht habe, die Schönheit dieses Algorithmus zu schätzen.
Prajeeth Emanuel
Ich würde vorschlagen, Pythons Implementierung zu verwenden, wenn Sie Geschwindigkeit anstreben
Derek 朕 會 功夫
@Derek 朕 會 功夫 Ah, klug, das funktioniert viel besser für kleine Proben aus großen Bereichen. Besonders mit einem ES6 Set(der in '13 nicht verfügbar war: - /)
Bergi
@AlexWhite Danke für das Feedback, ich kann nicht glauben, dass dieser Fehler jahrelang allen entgangen ist. Fest. Sie sollten jedoch einen Kommentar gepostet und keine Bearbeitung vorgeschlagen haben.
Bergi
1
@ cbdev420 Ja, es ist nur ein (teilweiser) Fischer-Yates-Shuffle
Bergi
175

Nur zwei Zeilen:

// 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);

DEMO :

Abdennour TOUMI
quelle
22
Sehr schön! Ein Liner ist natürlich auch möglich:let random = array.sort(() => .5 - Math.random()).slice(0,n)
unitario
1
Genius! Elegant, kurz und einfach, schnell und mit integrierten Funktionen.
Vlad
33
Es ist schön, aber alles andere als zufällig. Der erste Gegenstand hat viel mehr Chancen, ausgewählt zu werden als der letzte. Sehen Sie hier, warum: stackoverflow.com/a/18650169/1325646
pomber
Dies bewahrt nicht die Art des ursprünglichen Arrays
Almathie
2
Tolle! Wenn Sie das Array intakt halten möchten, können Sie die erste Zeile wie folgt ändern: const shuffled = [... array] .sort (() => 0.5 - Math.random ());
Yair Levy
16

Hier gibt es eine einzigartige Einzeiler-Lösung

 array.sort(() => Math.random() - Math.random()).slice(0, n)
Olalekan Sogunle
quelle
1
Während es funktioniert, kann es auch für größere Arrays langsam sein.
Philk
11

5 zufällige Elemente erhalten, ohne das ursprüngliche Array zu ändern:

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);

(Verwenden Sie dies nicht für große Listen)

pomber
quelle
Könnten wir besser erklären, wie das funktioniert?
Qasim
11

Portierung .sampleaus der Python-Standardbibliothek:

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;
}

Implementierung portiert von Lib / random.py .

Anmerkungen:

  • setsizewird basierend auf den Merkmalen in Python für die Effizienz festgelegt. Obwohl es nicht für JavaScript angepasst wurde, funktioniert der Algorithmus weiterhin wie erwartet.
  • Einige andere auf dieser Seite beschriebene Antworten sind gemäß der ECMAScript-Spezifikation aufgrund des Missbrauchs von nicht sicher Array.prototype.sort. Es wird jedoch garantiert, dass dieser Algorithmus in endlicher Zeit endet.
  • Für ältere Browser, die nicht Setimplementiert wurden, kann das Set durch ein Arrayund .has(j)durch ersetzt werden .indexOf(j) > -1.

Leistung gegen die akzeptierte Antwort:

Derek 朕 會 功夫
quelle
Ich habe unten eine optimierte Version dieses Codes veröffentlicht. Außerdem wurde der falsche Zufallsparameter im zweiten Algo in Ihrem Beitrag korrigiert. Ich frage mich, wie viele Leute die vorherige voreingenommene Version in der Produktion verwenden, hoffe nichts kritisches.
Benutzer
10

Erstellen Sie eine Funktion, die das tut:

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;
}

Sie sollten auch überprüfen, ob das sourceArray über genügend Elemente verfügt, um zurückgegeben zu werden. Wenn Sie eindeutige Elemente zurückgeben möchten, sollten Sie das ausgewählte Element aus dem sourceArray entfernen.

Laurynas Mališauskas
quelle
Gute Antwort! Schauen Sie sich meine Antwort an, kopieren Sie Ihren Code und fügen Sie die Funktion "Nur eindeutige Elemente" hinzu.
EvilReiko
1
Diese Funktion kann dasselbe Element sourceArraymehrmals zurückgeben.
Sampo
5

ES6-Syntax

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

Wenn Sie Elemente in einer Schleife ohne Wiederholungen zufällig aus dem Array abrufen möchten, können Sie das ausgewählte Element aus dem Array entfernen mit 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);

Rory McCrossan
quelle
1
Warum verwenden Sie in Anweisung items.splice (idx, 1) diese '1'? spleißen??
Shyam Dixit
2
Shyam Dixit , entsprechend der MDN - Dokumentation das 1ist die , deleteCountdie die Anzahl von alten Feldelemente zu entfernen. (Übrigens habe ich die letzten beiden Zeilen auf reduziert newItems.push(items.splice(idx, 1)[0])).
Kurt Peek
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();
吖 奇 说 - 何魏奇 Archy Will He
quelle
2

Hier ist eine schön getippte Version. Es scheitert nicht. Gibt ein gemischtes Array zurück, wenn die Stichprobengröße größer als die Länge des ursprünglichen Arrays ist.

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);
Daniel Birowsky Popeski
quelle
2

_.sampleund _.sampleSize.

Ruft ein oder n zufällige Elemente an eindeutigen Schlüsseln von der Sammlung bis zur Größe der Sammlung ab.

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

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

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

BEARBEITEN : Diese Lösung ist langsamer als andere hier vorgestellte (die das Quellarray spleißen), wenn Sie nur wenige Elemente erhalten möchten. Die Geschwindigkeit dieser Lösung hängt nur von der Anzahl der Elemente im ursprünglichen Array ab, während die Geschwindigkeit der Spleißlösung von der Anzahl der im Ausgabearray erforderlichen Elemente abhängt.

Wenn Sie nicht wiederholte zufällige Elemente möchten, können Sie Ihr Array mischen und dann nur so viele erhalten, wie Sie möchten:

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

DEMO: http://jsbin.com/UHUHuqi/1/edit

Shuffle-Funktion von hier übernommen: https://stackoverflow.com/a/6274398/1669279

Tibos
quelle
Dies hängt vom Prozentsatz der zufälligen Elemente ab, die vom Array benötigt werden. Wenn Sie 9 zufällige Elemente aus einem 10-Elemente-Array möchten, ist es sicherlich schneller zu mischen, als 9 zufällige Elemente nacheinander zu extrahieren. Wenn der Prozentsatz, für den dies nützlich ist, weniger als 50% beträgt, gibt es Anwendungsfälle, in denen diese Lösung am schnellsten ist. Ansonsten gebe ich zu, dass es nutzlos ist :).
Tibos
Ich meinte, dass das Mischen von 9 Elementen schneller ist als das Mischen von 10 Elementen. Übrigens bin ich zuversichtlich, dass der OP sein Eingabearray nicht zerstören will…
Bergi
Ich glaube nicht, dass ich verstehe, wie das Mischen von 9 Elementen bei diesem Problem hilft. Ich bin mir bewusst, dass Sie, wenn Sie mehr als die Hälfte des Arrays möchten, einfach zufällige Elemente herausschneiden können, bis Sie bei der gewünschten Anzahl bleiben, und dann mischen, um eine zufällige Reihenfolge zu erhalten. Gibt es etwas, das ich verpasst habe? PS: Array-Zerstörung behoben, danke.
Tibos
Es hat nichts mit "der Hälfte" zu tun. Sie müssen nur so viel Arbeit erledigen wie die Elemente, die Sie zurückerhalten möchten. Sie müssen zu keinem Zeitpunkt das gesamte Array behandeln. Ihr aktueller Code hat eine Komplexität von O(n+k)(n Elemente im Array, Sie möchten k davon), während O(k)dies möglich (und optimal) wäre.
Bergi
1
OK, Ihr Code hat mehr Ähnliches, O(2n)was reduziert werden könnte, O(n+k)wenn Sie die Schleife in ändern while (counter-- > len-k)und die letzten (anstelle der ersten) kElemente daraus entfernen würden. In splice(i, 1)der Tat nicht O(1), aber eine O(k)Lösung ist immer noch möglich (siehe meine Antwort). Die Raumkomplexität bleibt jedoch erhaltenO(n+k) leider erhalten, kann jedoch O(2k)von der Implementierung des spärlichen Arrays abhängen.
Bergi
1

Ich brauchte eine Funktion, um diese Art von Problem zu lösen, also teile ich sie hier.

    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);

Hinweis: Wenn Sie n = arr.lengthdann im Grunde genommen das Array mischen arrund randomItemsdas gemischte Array zurückgeben.

Demo

Speicher Lenovo
quelle
1

In dieser Antwort möchte ich Ihnen den Test mitteilen, dass ich die beste Methode kennen muss, mit der alle Elemente die gleiche Chance haben, ein zufälliges Subarray zu haben.

Methode 01

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

Bei dieser Methode haben einige Elemente im Vergleich zu anderen höhere Chancen.

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)

Methode 2

Mit dieser Methode haben die Elemente die gleiche Wahrscheinlichkeit:

 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)

Die richtige Antwort finden Sie unter folgendem Link: https://stackoverflow.com/a/46545530/3811640

Haouarin
quelle
0

Es extrahiert zufällige Elemente nacheinander aus srcArray, solange es ausreicht, oder es sind keine weiteren Elemente in srcArray zum Extrahieren übrig. Schnell und zuverlässig.

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;
}

Aleksey Yaremenko
quelle
Willkommen bei SO! Wenn Sie Antworten veröffentlichen, ist es wichtig zu erwähnen, wie Ihr Code funktioniert und / oder wie er das Problem von OP löst :)
Joel
0

2019

Dies entspricht der Antwort von Laurynas Mališauskas , nur dass die Elemente eindeutig sind (keine Duplikate).

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;
}

Um nun die ursprüngliche Frage "Wie man mit jQuery mehrere zufällige Elemente erhält" zu beantworten, geht es los:

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');
böseReiko
quelle
0

Hier ist eine Funktion, mit der Sie ein Array mit oder ohne Ersatz einfach abtasten können:

  // 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;
  };

Die Verwendung ist einfach:

Ohne Ersatz (Standardverhalten)

randomSample([1, 2, 3], 2) kann zurückkehren [2, 1]

Mit Ersatz

randomSample([1, 2, 3, 4, 5, 6], 4) kann zurückkehren [2, 3, 3, 2]

Jared Wilber
quelle
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;
}
Manoj Rana
quelle
0

Ich kann nicht glauben, dass niemand diese Methode nicht erwähnt hat, ziemlich sauber und direkt.

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

Hier ist eine optimierte Version des Code von Python von @Derek portierte, mit der zusätzlichen destruktiven (in-place) Option , die es den schnellste Algorithmus ermöglicht , wenn Sie mit ihm gehen. Andernfalls wird entweder eine vollständige Kopie erstellt oder für eine kleine Anzahl von Elementen, die von einem großen Array angefordert werden, auf einen auswahlbasierten Algorithmus umgeschaltet.

// 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]);
    }
}

Im Vergleich zu Dereks Implementierung ist der erste Algorithmus in Firefox viel schneller und in Chrome etwas langsamer, obwohl er jetzt die destruktive Option hat - die leistungsstärkste. Der zweite Algorithmus ist einfach 5-15% schneller. Ich versuche, keine konkreten Zahlen anzugeben, da diese je nach k und n variieren und mit den neuen Browserversionen in Zukunft wahrscheinlich nichts mehr bedeuten werden.

Die Heuristik, die die Wahl zwischen Algorithmen trifft, stammt aus Python-Code. Ich habe es so belassen, wie es ist, obwohl es manchmal das langsamere auswählt. Es sollte für JS optimiert werden, ist jedoch eine komplexe Aufgabe, da die Leistung von Eckfällen browser- und versionabhängig ist. Wenn Sie beispielsweise versuchen, 20 von 1000 oder 1050 auszuwählen, wird entsprechend zum ersten oder zweiten Algorithmus gewechselt. In diesem Fall läuft der erste 2x schneller als der zweite in Chrome 80, aber 3x langsamer in Firefox 74.

Benutzer
quelle
-1

Hier ist die richtigste Antwort und es gibt Ihnen zufällige + eindeutige Elemente.

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
Nivesh Saharan
quelle
Es ist etwas Seltsames mit der Randomisierung in diesem - ich hatte das gleiche Ergebnis 6 von 9 Versuchen (mit einem n von 8 und einer Array-Größe von 148). Sie könnten darüber nachdenken, auf eine Fisher-Yates- Methode umzusteigen. es ist was ich getan habe und jetzt funktioniert es viel besser.
Asetniop
Dies dauert quadratisch, da eine schlechte Eindeutigkeitsprüfung durchgeführt wird und nicht die gleiche Chance besteht, jedes Element auszuwählen, da es nach einem zufälligen Vergleich sortiert wird.
Ry-
-1

items.sort (() => (Math.random ()> 0,5? 1: -1)). Slice (0, count);

Yauheni Charniauski
quelle