Hi,
Each VU in independent. It means that each VU has no idea what other VU is doing, also there is no way of “informing” other VUs what that particular VU has done.
In your example we have an array of 5 element. If you pick an element at random and even remove it from the array other VUs still will be able to pick that element. That is because each of which has its own array of 5 elements. There is no shared resource that each VU can alter.
What you can do, is to use scenario.iterationInTest but you change the order of the elements in the mentioned array before the test:

function shuffle(array) {
for (let i = array.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1))
[array[i], array[j]] = [array[j], array[i]]
}
}

This way you will avoid repeptiveness of your tests.

We used a slightly different approach that essentially splits the array into chunks so that there is no overlap across VUs. Ours iterates through the array in order, but you could likely easily swap that portion with a randomizer:

export function getDataIndex(maxLength) {
const globalStartingIndex = getStartingDataIndex();
var multiplier = 0;
let vus = getMaxVuCount();
if (vus === undefined) {
vus = maxLength;
}
if (maxLength > vus) {
// Split the data file into multiple parts
multiplier = parseInt(`${maxLength / vus}`);
} else {
// At minimum, stagger the VUs by 1
multiplier = 1;
}
// The below examples are for VU 16 of 200, with a data size of 1000,
// and iteration 8.
// The end result is that each VU gets 5 data items to loop over.
// So VU 16 gets to use indexes 75-79, so on iteration 0,
// it gets index 75, iteration 1 is idx 76, up to iteration 4 = idx 79.
// Then it starts over with iteration 5 getting idx 75
// and iter 8 getting idx 78.
// Step 1: Get the lower boundary for this VU (vuStartingIndex)
// by multiplying its VU number by the multiplier
// and then adding the globalStartingIndex if applicable.
// E.g., ((16 -1) * 5) % 1000 = 75
const vuStartingIndex =
globalStartingIndex + (((getVuNumber() - 1) * multiplier) % maxLength);
// Step 2: Get the upper boundary (vuMaxIndex)
// by adding the multiplier to the lower boundary.
// E.g., 75 + 5 - 1 = 79
const vuMaxIndex = vuStartingIndex + multiplier - 1;
// Step 3: Calculate the length of the data subset for this VU (range).
// E.g., 79 - 75 + 1 = 5
const range = vuMaxIndex - vuStartingIndex + 1;
// Step 4: Loop over this subset to find the appropriate index (idx)
// for this VU.
// E.g., 75 + (8 % range) = 78
const idx = vuStartingIndex + (__ITER % range);
return idx;
}