I am trying to generate a random ID on a very explicit set of requirements.
There are 3 arrays itemsAvailable, itemsSeen, and itemsTaken.
itemsAvailable looks like this: [{ id: 1, ... }, ...] an array of objects with various fields, the other fields don't matter for the purposes of this functionality, we are only concerned with the id field. It is a number that is 1 -> X, X increasing by 1 for each item present.
itemsSeen is just an array of the ids that a user has seen, so if they saw ids for 1, 7, 16 it would look like itemsSeen = [1, 7, 16].
itemsTaken is also just an array of the ids they have seen that they chose to take, for example, itemsTaken = [1, 16]. They can only take items that have been present in itemsSeen.
At the start of the function, a random id is generated based on the length of itemsAvailable. Each item's id will match its index position.
If itemsSeen or itemsTaken includes the random id, generate a new one in the bounds of the length of itemsAvailable until it is not present in either array.
When a number is generated and shown to the user, it should be added to itemsSeen array. If that item is picked it should be added to itemsAvailable array. Then get a random item from itemsAvaialbe again.
code sandbox of what I have.
Thanks to Barmar for helping simplify the solution.
I changed the implementation to only use two arrays, picking a random item from the first array, removing it, and then adding it to the second array.
var itemsAvailable = [];
var currentItem;
for (let i = 0; i < 25; i++) {
itemsAvailable.push({ id: i });
}
var itemsSeen = [{ id: 3 }, { id: 7 }, { id: 16 }];
const getRandomId = (arr, length) => {
var r = arr[Math.floor(Math.random() * length)];
if (itemsSeen.includes(r)) {
r = arr[Math.floor(Math.random() * length)];
}
return r;
};
const generateRandomId = () => {
if (itemsAvailable.length === 0) {
return;
}
var nextItem = getRandomId(itemsAvailable, itemsAvailable.length);
itemsSeen.push(nextItem);
itemsAvailable = itemsAvailable.filter((item) => item !== nextItem);
currentItem = nextItem;
};