I have an array of 50 objects as elements.
Each object contains an array of 4 elements:
var all = [{
question: "question 1 goes here",
options: ["A", "B", "C", "D"]
}, ... {
question: "question 50",
options: ["A", "B", "C", "D"]
}]
I want to select 10 elements randomly and save to two other arrays, one of the array I want to shuffle options. but when shuffling both arrays are affected.
var selected = [];
var shuffled = [];
for(let i = 0; i < 10; i++) {
let rand = Math.floor(Math.random() * all.length);
selected.push(all[rand]);
shuffled.push(all[rand]);
all.splice(rand, 1);
for(let j = 3; j > 0; j--) {
let rand2 = Math.floor(Math.random() * j);
[
shuffled[i].options[j],
shuffled[i].options[rand2]
] = [
shuffled[i].options[rand2],
shuffled[i].options[j]
];
}
}
console.log(selected); // is shuffled too
console.log(shuffled);
How do I prevent that?
I feel like I'm missing something pretty simple, but I can't spot it.
You need to create new instances for the chosen objects and their
options
arrays:I consigned the shuffle algorithm to a separate function (
shuffle()
) and applied it twice: first to theall
array to make sure we don't get any duplicates in our "random" selection and then to theoptions
arrays contained within their sliced-off objects. The functionshuffle(a,len)
sorts arraya
in place. I made it return the array reference again purely out of convenience, as it helps me keep my code more compact. The optional argumentlen
will cause the arraya
to be shortened tolen
shuffled elements (still "in place": the input array will be affected too!).So, in order to preserve my "input" arrays I created new array instances each time I called the function by applying the
...
operator: