0

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!

1
  • I've tried splitting the process into two functions, one for shuffling and another for reordering, but the results are never consistent. Commented May 9, 2014 at 17:39

2 Answers 2

1

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;
}
Sign up to request clarification or add additional context in comments.

2 Comments

"not sure if it works" Why would you post it as an answer then?
Yup, it's working. Fixed some minor JS errors: jsfiddle.net/n2kKd Thanks Hristo
1

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]);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.