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.

1
  • Have you considered using some sort of hashing mechanism? Commented Mar 20, 2011 at 21:01

3 Answers 3

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

Comments

1

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.

Comments

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.

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.