Selecting another value from array in javascript
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]
source to share
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.
source to share
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));
source to share
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))];
source to share
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
source to share