Selecting another value from array in javascript

What is the best way in JavaScript given an array of ids:

var ids = ['ax6484', 'hx1789', 'qp0532'];

      

and the current id hx1789

to select a different value at random , which is not the current one from the ids array?

+3


source to share


5 answers


Get the index of the value, generate a random value, if the index is random, use 1 less (depending on the random generation)

var random = Math.floor(Math.random() * ids.length)
var valueIndex = ids.indexOf("hx1789");

if (random === valueIndex) {
    if (random === 0) {
        random = 1;
    } else {
        random = random - 1;
    }
}

var randomValue = ids[random];

      

Demo: http://jsfiddle.net/sxzayno7/

And yes, check the length of the array if it's 1 - probably doesn't want to! Thanks @ThomasStringer



if (ids.length > 1) { //do it! }

      

Or just filter the value and pull it in:

var randomIndex = Math.floor(Math.random() * (ids.length - 1))
var random = ids.filter(function(id) {
    return id !== "hx1789";
})[randomIndex]

      

+5


source


I would probably do something like:

var current = 'hx1789'; // whatever variable stores your current element

var random = Math.floor(Math.random() * ids.length);
if(random === ids.indexOf(current)) {
    random = (random + 1) % ids.length;
}

current = ids[random];

      



Basically, if the newly selected element is at the same index, you simply select the next element from the array, or if it is out of bounds, select the first one.

+1


source


UnderscoreJS is your best friend!

_.sample(_.without(['ax6484', 'hx1789', 'qp0532'], 'hx1789'));

      

or with variables;

var myArray = ['ax6484', 'hx1789', 'qp0532'];
var currentId = 'hx1789';

var newRandomId = _.sample(_.without(myArray , currentId));

      

+1


source


You can create a duplicate array and then remove the current inode from that array and pick a random item from the duplicate with the removed item:

var ids = ['ax6484', 'hx1789', 'qp0532'];
var currentIndex = ids.indexOf('hx1789');
var subA = ids.slice(0);
subA.splice(currentIndex , 1);
var randItem = subA[Math.floor((Math.random() * subA.length))];

      

An example is here .

0


source


It gets trickier if your value is not a simple string like hx1789

, but rather, for example, comes from an array in an array from which you want to generate another value:

let weekSegments = [["Su","Mo"],["Tu","We"],["Th","Fr","Sa"]];

      

If you have an index, it's simple, no matter how deeply nested the array (or object) and / or the types of values ​​it contains:

let index = 1;
let segment = weekSegments[index];
let randomIndex;
let randomSegment;

if (weekSegments.length >= 1) {
    randomIndex = Math.floor(Math.random) * (weekSegments.length - 1);
    randomSegment = weekSegments.filter((val, i) => i !== index)[randomIndex];
}

      

Without an index, although things get complicated by the need to match the array and / or object in the filter function. In the above example, this is pretty straightforward because it is an array that is only sibling depth, which in turn only contains simple values. First, we create a string representation of the sorted segment values ​​that we already have, and then compare them to the string representation val

at each iteration filter

:

let segmentVals = segment.sort().join(',');

if (weekSegments.length > 1) {
    randomIndex = Math.floor(Math.random) * (weekSegments.length - 1);
    randomSegment = weekSegments.filter((val) => {
        return segmentVal !== val.sort().join(',');
    })[randomIndex];
}

      

When dealing with objects, rather than arrays and / or arrays / objects that are deeply nested and / or contain non-nested values, it goes into the sticky matter of object equality, which is probably not entirely consistent with this Q&A

0


source







All Articles