ray1
ray1

Reputation: 4048

JavaScript randomize array but keep certain pairs

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

Answers (2)

kennebec
kennebec

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

Hristo Ivanov
Hristo Ivanov

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

Related Questions