简体   繁体   中英

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 a current id hx1789 to select another value at random that is not the current from the ids array?

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

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 yeah, test the array length, if it's 1 - probably don't want to do this! Thanks @ThomasStringer

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

Or just filter out the value and pull against that:

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

I would probably do something along the lines of:

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 picked element sits on the same index, you just pick the next element from the array, or if that goes out of bounds, pick the first.

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

You could make a duplicate array, then remove the current indexed element from that array and select an random element 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))];

Example Here .

This gets trickier if your value is not a simple string such as hx1789 but rather for instance comes from an array within the array you want to generate a different value from:

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

If you have the index it's simple, no matter how deeply nested the array (or object) is and/or the types of the 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 the index though things get more complicated due to having to test for array and/or object equality in the filter function. In the case above it's fairly easy because it's an array that is only one-level deep which in turn only contains simple values. First we create a string representation of the sorted segment values we already have, then compare that to a string representation of val on each filter iteration:

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 devolves into the sticky matter of object equality that is probably not entirely germane to this Q&A

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM