Reputation: 4048
I'm trying to shuffle an array but I want to keep some values in tact. This excellent answer here on SO shows how to shuffle but I want to be able to specify an additional parameter that takes an array of values to keep.
This is what I'm trying to achieve. Say I have an array:
[1, 2, 3, 4, 5]
I want to run my shuffle function like this:
shuffle(arr, [1, 3])
This means, shuffle the array but keep arr[1]
and arr[3]
in tact. So I should get:
[3, 2, 1, 4, 5]
[5, 2, 3, 4, 1] etc...
Notice how 2
and 4
never changed their places.
Any help is appreciated!
Upvotes: 0
Views: 632
Reputation: 104780
This one uses an array method that returns one random element from an array.
The function slices a new array and removes the keepers from it,
then randomly replaces only those indexes that are 'shuffleable'.
The keepers are inserted unchanged.
Array.prototype.getRandom= function(cut){
var i= Math.floor(Math.random()*this.length);
if(cut) return this.splice(i, 1)[0];
return this[i];
}
function customShuffle(arr, save){
var A= [], B= arr.slice(),
tem, L= arr.length, LS= save.length;
while(LS){
tem= save[--LS];
B.splice(tem, 1);
}
for(var j= 0; j<L; j++){
if(save.indexOf(j)!= -1) A[j]= arr[j];
else A[j]= B.getRandom(1);
}
return A;
}
var arr= [1, 2, 3, 4, 5, 6, 7, 8, 9];
customShuffle(arr, [1, 3, 7]);
Upvotes: 1
Reputation: 719
Havent tried it and i coded it in litle time. not sure if it works but i think the idea is worth: take out the elements we dont want to shufle, shufle what is left, put back those elements on their positions. Take look at: splice()
function shuffle(array) {
var currentIndex = array.length
, temporaryValue
, randomIndex
;
// While there remain elements to shuffle...
while ( 0 !== currentIndex ) {
// Pick a remaining element...
randomIndex = Math.floor(Math.random() * currentIndex);
currentIndex -= 1;
// And swap it with the current element.
temporaryValue = array[currentIndex];
array[currentIndex] = array[randomIndex];
array[randomIndex] = temporaryValue;
}
return array;
}
function shuffle2(array,aux){
var i;
var keeper = [];
for( i = 0; i < aux.length; i++ ) {
keeper[i] = array[aux[i]];
}
for ( i = aux.length-1; i >= 0; i-- ) { // It's important to do this from the last to the first
array.splice(aux[i], 1); // This will remove the index element shifting the rest of elemnts
}
shuffle(array);
// Now we put back the elements we took out.
for ( i = 0; i < aux.length; i++ ) {
array.splice(aux[i], 0, keeper[i]); // This will remove the index element shifting the rest of elemnts
}
return array;
}
Upvotes: 1