How to make a function that selects randomly the array elements?

Hello! It would seem trivial, but I can't think of how to make a function that will accept as parameter the number of returned elements, and the array from which we will isolate them (sorry)!

let arr = [ 1, 2, 3, 4, 5, 6, 7 ];
function getRandom( n, array ) { // n is the number of random elements from array
 // . . . code which will allow you to obtain a certain number of elements from the array
};

getRandom( 3, arr ); // must succeed for example [4, 6, 7] or [1, 4, 6]

! ! ! I wrote a implementation of this function, BUT it has a disadvantage , which I urge you to consider

let arr = [1,2,3,4,5,6,7,8,9,10];

getRandomRiver function(n, a){
 let result = []; 
 for(let k=0; k<a.length; k++){
 if(!Math.the round(Math.random())) result.push(a[k]); // Math.the round(Math.random()) returns either 0 or 1, if 0 then we add this element to the array
 if(result.length>=n) break; 
};
console.log(result);
};

getRandomRiver(3, arr);

The fact that this function in 1ВЫХ may return fewer , and in OF 2, every time she sees the elements of the array with 0го index, and the chance that in a variable result will get the elements closer to the end of the array is very small, and I need a full Rand covering the full array! Thank you in advance!
April 19th 20 at 12:48
2 answers
April 19th 20 at 12:50
Solution
const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

getRandomRiver function(n, arr) {
 const indexes = new Set();
 const limit = arr.length;
 n = Math.min(n, limit);
 while (indexes.size < n) {
 const index = Math.floor(limit * Math.random());
indexes.add(index);
}
 const result = [...indexes].map(index => arr[index]);
 return result;
};

const randomSet = getRandomRiver(3, arr);
console.log(randomSet);
hmm, thanks for the solution, but I do not understand until the ES6 syntax, therefore, I note your answer, BUT will return to it later. - haven_Corke commented on April 19th 20 at 12:53
@haven_Corke, if you're talking about [indexes...], this is equivalent to Array.from(indexes).

If you talk, why the solution @kaylie sub-optimal, then all the matter in the average number of operations that will be produced during operation of the algorithm.

Let the initial array will have N elements. Then when sorting occurs at least N · log(N) operations. It is still possible to add N operations on every call .map().

In the end, if an array of 1000 elements it is necessary to choose 3 items, it will be absolutely approximately 12,000 operations.

In the proposed embodiment, the number of operations depends not on the number of elements in the array, and the number of elements that have to choose. And if you re to consider an array of 1000 elements from which to choose 3 elements, the algorithm, proposed by me, will spend a total of 12 operations. - malika.Boyer92 commented on April 19th 20 at 12:56
@malika.Boyer92, nice trick with a while (indexes.size < n) for the case where the random number will repeat :) - misael_Rippin commented on April 19th 20 at 12:59
@misael_Rippin, yeah, that's it for this =) - malika.Boyer92 commented on April 19th 20 at 13:02
April 19th 20 at 12:52
Solution
const getRandomRiver = (n, arr) => arr.sort(() => 0.5 - Math.random()).slice(0, n);

or
const getRandomRiver = (n, arr) => {
 return arr
 .map(x => ({ x, r: Math.random() }))
 .sort((a, b) => a.r - b.r)
 .map(a => a.x)
 .slice(0, n);
}


upd: or keep like wanted
Hmm, cool, peretasoval array and return the first three elements are, huh! God, I feel stupid! The second example I have not yet dismantled, I think in my case and the first will be limited! Damn well, how is it then, well, it's damn easy !=// - haven_Corke commented on April 19th 20 at 12:55
@haven_Corke, this is a VERY suboptimal solution - malika.Boyer92 commented on April 19th 20 at 12:58

Find more questions by tags JavaScript