# How to get n no elements randomly from an array

I am working on 'how to access elements randomly from an array in javascript'. I found many links regarding this. Like: Get random item from JavaScript array

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

Question: But in this we can choose only one item from the array.If we want more than one elements then how can we achieve this.So please just from this statement how can we get more than one elements from an array. Try this non-destructive (and fast) function:

``````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;
}
`````` Just two lines :

``````// 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: create a funcion which does that:

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

you should also check if the sourceArray has enough elements to be returned. and if you want unique elements returned, you should remove selected element from the sourceArray. Getting 5 random items without changing the original array:

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

(Don't use this for big lists) Porting `.sample` from the Python standard library:

``````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 - i) | 0;
while(selected.has(j)){
j = Math.random() * (n - i) | 0;
}
result[i] = population[j];
}
}

return result;
}
``````

Implementation ported from Lib/random.py.

Notes:

• `setsize` is set based on characteristics in Python for efficiency. Although it has not been adjusted for JavaScript, the algorithm will still function as expected.
• Some other answers described in this page are not safe according to the ECMAScript specification due to the misuse of `Array.prototype.sort`. This algorithm however is guaranteed to terminate in finite time.
• For older browsers that do not have `Set` implemented, the set can be replaced with an `Array` and `.has(j)` replaced with `.indexOf(j) > -1`. There is a one-liner unique solution here

`````` array.sort(() => Math.random() - Math.random()).slice(0, n)
`````` If you want to randomly get items from the array in a loop without repetitions you need to remove the selected item from the array with `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);
}
``````

Example fiddle I needed a function to solve this kind of issue so I'm sharing it here.

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

Note: if `n = arr.length` then basically you're shuffling the array `arr` and `randomItems` returns that shuffled array.

Demo Here's a nicely typed version. It doesn't fail. Returns a shuffled array if sample size is larger than original array's length.

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

const randomIntFromInterval = (min: number, max: number): number =>
Math.floor(Math.random() * (max - min + 1) + min);
`````` It extracts random elements from srcArray one by one while it get's enough or there is no more elements in srcArray left for extracting. Fast and reliable.

``````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;
}`````` ``````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;
}
`````` In this answer, I want to share with you the test that I have to know the best method that gives equal chances for all elements to have random subarray.

# Method 01

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

using this method, some elements have higher chances comparing with others.

``````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===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)``````

# Method 2

Using this method, the elements have the same probability:

`````` 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===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)`````` items.sort(() => (Math.random() > 0.5 ? 1 : -1)).slice(0, count); Here is the most correct answer and it will give you Random + Unique elements.

``````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
`````` ES6 syntax

``````const pickRandom = (arr,count) => {
let _arr = [...arr];
return[...Array(count)].map( ()=> _arr.splice(Math.floor(Math.random() * _arr.length), 1) );
}
`````` ``````Array.prototype.getnkill = function() {
var a = Math.floor(Math.random()*this.length);
this.splice(a,1);
}

//.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();
`````` EDIT: This solution is slower than others presented here (which splice the source array) if you want to get only a few elements. The speed of this solution depends only on the number of elements in the original array, while the speed of the splicing solution depends on the number of elements required in the output array.

If you want non-repeating random elements, you can shuffle your array then get only as many as you want:

``````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
``````

Shuffle function taken from here: https://stackoverflow.com/a/6274398/1669279 2019

This is same as Laurynas Mališauskas answer, just that the elements are unique (no duplicates).

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

Now to answer original question "How to get multiple random elements by jQuery", here you go:

``````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.css('backgroundColor', 'red');
`````` Here's a function I use that allows you to easily sample an array with or without replacement:

``````  // 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 < b ? -1 : 1;}).slice(0, k).map(a => a);
};
return sample;
};
``````

Using it is simple:

Without Replacement (default behavior)

`randomSample([1, 2, 3], 2)` may return `[2, 1]`

With Replacement

`randomSample([1, 2, 3, 4, 5, 6], 4)` may return `[2, 3, 3, 2]` I can't believe that none didn't mention this method, pretty clean and straight forward.

``````const getRnd = (a, n) => new Array(n).fill(null).map(() => a[Math.floor(Math.random() * a.length)]);
`````` Here's an optimized version of the code ported from Python by @Derek, with the added destructive (in-place) option that makes it the fastest algorithm possible if you can go with it. Otherwise it either makes a full copy or, for a small number of items requested from a large array, switches to a selection-based algorithm.

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

In comparison to Derek's implementation, the first algorithm is much faster in Firefox while being a bit slower in Chrome, although now it has the destructive option - the most performant one. The second algorithm is simply 5-15% faster. I try not to give any concrete numbers since they vary depending on k and n and probably won't mean anything in the future with the new browser versions.

The heuristic that makes the choice between algorithms originates from Python code. I've left it as is, although it sometimes selects the slower one. It should be optimized for JS, but it's a complex task since the performance of corner cases is browser- and their version-dependent. For example, when you try to select 20 out of 1000 or 1050, it will switch to the first or the second algorithm accordingly. In this case the first one runs 2x faster than the second one in Chrome 80 but 3x slower in Firefox 74. `_.sample` and `_.sampleSize`.

Gets one or n random elements at unique keys from collection up to the size of collection.

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

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

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