3

I have a javascript array that I'd like to be sorted according to a number or string that I specify. I'd like the array to appear to be randomly sorted, but the array would always be sorted the same if the input was "6543", for example.

makeee
  • 2,765
  • 5
  • 35
  • 42

3 Answers3

3

Javascript in itself doesn't offer this functionality – its RNG can't be seeded. There are still different approaches one can take. Here's one. The seed must be greater than one (or the same array will be returned), and should be greater than the array size for sufficient "randomness".

Array.prototype.deterministicShuffle=function(seed){
    // A little error handling, whynot!
    if(!seed)
        throw new Error("deterministicShuffle: seed not given, or 0");

    var temp,j;

    for(var i=0; i<this.length; i++){
        // Select a "random" position.
        j = (seed % (i+1) + i) % this.length;

        // Swap the current element with the "random" one.
        temp=this[i];
        this[i]=this[j];
        this[j]=temp;

    }

    return this;
}

// Try it out, Aaron!    
alert([0,1,2,3,4,5,6,7,8,9].deterministicShuffle(6543));
alert([0,1,2,3,4,5,6,7,8,9].deterministicShuffle(6544));
alert([0,1,2,3,4,5,6,7,8,9].deterministicShuffle(6545));
nitro2k01
  • 7,627
  • 4
  • 25
  • 30
2

Use a shuffle function and replace Math.random() by a random number generator where you can set your own seed. Then set your seed to your input number.

Community
  • 1
  • 1
Alex
  • 32,506
  • 16
  • 106
  • 171
0

With such a small seed and array to work with, you are going to need to get creative with my example.

As Alex suggested, there is a good shuffle function at the site he provided. I've combined that with another function to get the ascii value of the seed.

You should strongly consider changing my example to hash the input. Otherwise there will be a lot of collision.

Here is the code:

<script>

    // http://sharkysoft.com/tutorials/jsa/content/018.html
    function ascii_value (c)
    {
        // restrict input to a single character
        c = c . charAt (0);

        // loop through all possible ASCII values
        var i;
        for (i = 0; i < 256; ++ i)
        {
            // convert i into a 2-digit hex string
            var h = i . toString (16);
            if (h . length == 1)
                h = "0" + h;

            // insert a % character into the string
            h = "%" + h;

            // determine the character represented by the escape code
            h = unescape (h);

            // if the characters match, we've found the ASCII value
            if (h == c)
                break;
        }
        return i;
    }

    // http://snippets.dzone.com/posts/show/849
    shuffle = function(o,seed){ //v1.0

        for(var j, x, i = o.length; i; j = parseInt(seed / (o.length * 255) * i), x = o[--i], o[i] = o[j], o[j] = x);
        return o;
    };


    function seedSort (string){
        var charList = string.split('');
        var seedValue = 0;
        for(var i in charList){

            seedValue += ascii_value(charList[i]);

        }
        return seedValue;
    }

    document.write(shuffle([0, 1, 2, 3, 4, 5, 6, 7, 8, 9],seedSort("bob")));
    document.write("<br>");
    document.write(shuffle([0, 1, 2, 3, 4, 5, 6, 7, 8, 9],seedSort("steve")));
    document.write("<br>");
    document.write(shuffle([0, 1, 2, 3, 4, 5, 6, 7, 8, 9],seedSort("david's house")));
    document.write("<br>");
    document.write(shuffle([0, 1, 2, 3, 4, 5, 6, 7, 8, 9],seedSort("acorn22")));


</script> 

This will produce

8,2,3,4,5,6,7,0,9,1
4,9,3,0,5,6,7,8,1,2
8,0,6,1,5,2,7,3,9,4
4,8,3,0,5,6,7,1,9,2

... which "appear" random. I'd suggest big seeds though.

Caterham
  • 2,301
  • 1
  • 13
  • 8