How to choose a random array element in Javascript?

Asked

Viewed 129 times

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?

  • 1

    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. :)

  • 2

    +1 these initiatives are good for the community and still have people who negative.... will understand.

2 answers

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

You are not signed in. Login or sign up in order to post.