4
I already know how shuffle an array, but how do I choose a random element of arrays?
let arr = ['a', 'b', 'c'];
How do I choose any element of arr
?
4
I already know how shuffle an array, but how do I choose a random element of arrays?
let arr = ['a', 'b', 'c'];
How do I choose any element of arr
?
5
Just choose an index within the limits of the array and then index it:
// Escolhendo o índice aleatório para o array `arr`:
const randomIndex = Math.floor(Math.random() * arr.length);
// Indexando o elemento aleatório de `arr` a partir do índice:
const randomElement = arr[randomIndex];
Or, in a single line:
const randomElement = arr[Math.floor(Math.random() * arr.length)];
This works for any element of arr
(no matter the length of the array) once the function Math.random
always returns a number between inclusive 0 and unique 1, so that the function Math.floor
always round down the product, which always results in a valid array index.
For example:
const arr = ['a', 'b', 'c'];
const randomElement = arr[Math.floor(Math.random() * arr.length)];
console.log(randomElement);
3
A suggestion made by @K-Gun would use bitwise operator ~
(NOT) twice to approach the integer, for example:
let value = 5;
console.log(value); // 0000000000000101
console.log(~value); // 1111111111111010
console.log(~~value); // 0000000000000101
value = 5.5;
console.log(value); // 0000000000000101.1
console.log(~value); // 1111111111111010
console.log(~~value); // 0000000000000101
Or you can also use bitwise |
(OR) with the value 0
, example:
let value = 5.6;
console.log(value | 0);
Example of use:
const arr = ['a', 'b', 'c'];
const result1 = arr[~~(Math.random() * arr.length)];
const result2 = arr[Math.random() * arr.length | 0];
console.log('Resultado com ~~:', result1, 'Resultado com "| 0":', result2);
Using Bitwise in this case was 4% to 12% (approximately) faster than using Math.floor()
(depends on the engine used, apparently on the V8 or Math.floor
was a little more efficient than on other engines).
If the goal is to catch a value just will not notice difference, but if the goal is to get several random values, you may have a small time advantage using bitwise.
View online test to compare performance: https://jsbench.me/jcko4lx25k/1
With browsers the results sometimes vary a little, so I created a script to run in Nodejs with lib
It had the following result:
C:\Users\inphinitphp\brcontainer\benchjs>node index.js
<testMathFloor> x 70,626,567 ops/sec ±4.74% (83 runs sampled)
<testNotBitwise> x 85,974,804 ops/sec ±1.45% (90 runs sampled)
<testOrBitwise> x 83,772,645 ops/sec ±1.84% (88 runs sampled)
Fastest is <testNotBitwise>,<testOrBitwise>
Being ~~
and | 0
the fastest, follows source code for testing:
var Benchmark = require('benchmark');
var suite = new Benchmark.Suite;
const arr = ['a', 'b', 'c'];
suite
.add('<testMathFloor>', testMathFloor)
.add('<testNotBitwise>', testNotBitwise)
.add('<testOrBitwise>', testOrBitwise);
// add listeners
suite
.on('cycle', function(event) {
console.log(String(event.target));
})
.on('complete', function() {
console.log('Fastest is ' + this.filter('fastest').map('name'));
})
// run async
.run({ 'async': false });
function testMathFloor()
{
arr[Math.floor(Math.random() * arr.length)];
}
function testNotBitwise()
{
arr[~~(Math.random() * arr.length)];
}
function testOrBitwise()
{
arr[Math.random() * arr.length | 0];
}
In modern environments it may be less "obscure" to use the Math.trunc
instead of ~~
. Anyway, I still prefer the floor
, classic in this situation. I will still comment that performance should not be a very decisive factor in JS. If it is important, it is in the wrong language. : D
Performance in case of having many operations and no language choice, no sense to write in C for browsers, I’m only talking about amount of operations.
Browser other questions tagged javascript array
You are not signed in. Login or sign up in order to post.
I ended up posting because I find something interesting and still not on the site. If the person wants to justify the -1 would be happy to know. :)
– Luiz Felipe
+1 these initiatives are good for the community and still have people who negative.... will understand.
– Cmte Cardeal