Custom (Bad) Shuffling in javascript (troubleshoot)

I just wanted to try an own shuffle function myself. But it doesn’t seem to work. I don’t really know why it wouldn’t work, because i double checked and went through the loop manually etc. So I would appreciate a second pair of eyes :wink:

function shuffle(array) {
  var randomIndex;
  var io;
  var tempi = [""];
  while (0 !== array.length) {
    randomIndex = Math.floor(Math.random() * array.length);
    io = array[randomIndex];
    array.splice(randomIndex,1);
    tempi.push(io);
  }
array = tempi;
return array;
}

I know there are very good shuffling functions out there (I will use fisher-yates algorithm for my program ) But I wanted to see how this custom algorithm performs on https://bost.ocks.org/mike/shuffle/compare.html

You’re seeding the resultant array with an empty string, so the output will always include that: shuffle([]) will be [""] for example.

Also:

  • array = tempi; – why not just return tempi? it’s literally the same
  • this is super inefficient, you’re taking values out of one array (recalculating the size of that array), then putting them into a different array. Just swapping the values in the existing array is efficient & easier
1 Like

If you want good shuffling algorithm, you need to account that for following formula:

const randomInt = Math.floor(Math.random() * n);

The bigger n more random the randomInt. In your case randomness is being decreased as loop progresses - and it’s considered not a good practice.

Try to map through the array, appending to each item random integer with n at least 10 or 100 times the array length, they sort array by integer and finally map it again removing appended value. To me it sounds like extremely random shuffling :slight_smile:

2 Likes

thank you. I saw now that the function actually works but I called it with this shuffle(array) instead of array = shuffle(array). I didn’t know function would just return the value and not the variabe with the value.

  • array = tempi; – why not just return tempi ? it’s literally the same
  • this is super inefficient, you’re taking values out of one array (recalculating the size of that array), >then putting them into a different array. Just swapping the values in the existing array is efficient & easier

thank you for these 2 points

  • I wasn’t 100% sure it was possible to return a different variable than the parameter in the function. (Apparently oc you can haha)
  • Yes it is very inefficient, in my actual program I’ll use fischer yates as you suggested (flipping the values)

I am a literal beginner, and I wanted to try things out on the go instead of doing those online courses, because they are so boring and I can’t remember anything of it (did a codecademy course once). But it seems, that I maybe shoud go over some basic stuff again.

Since you are here ;D I’d like to ask another question:
In my project that I’m working at, i have div Elements of a class, which I want to shuffle with the fisher-yates shuffle. The problem is, that with getElementsbyclass(".cards"); or querySelectorAll I don’t get an array, I get a nodeList, or an arry like object. And apparently I can’t just put this thing into the shuffle function. I searched how to convert this nodeList into an array, but couldn’t find the solution yet

fisher-yates shuffle

function shuffle(array) {
  var remainingElements = array.length;
  var temporaryValue, randomIndex;

  // While there remain elements to shuffle...
  while (0 !== remainingElements) {

    // Pick a remaining element...
    randomIndex = Math.floor(Math.random() * remainingElements);
    remainingElements -= 1;

    // And swap it with the current element.
    temporaryValue = array[remainingElements];
    array[remainingElements] = array[randomIndex];
    array[randomIndex] = temporaryValue;
  }
  return array;
}

You guys don’t have to answer, you already did help me a lot, thank you :wink: I’ll figure it out at some point, but it may take a long time xD. Any tips for learning are also much appreciated, if you have (more) time.

const realArray = Array.from(document.querySelectorAll('.cards'));

OR

const realArray = Array.prototype.slice.call(document.querySelectorAll('.cards'));

OR

const realArray = [ ...document.querySelectorAll('.cards') ];
1 Like

thank you

I didn’t really understand that, why is a smaller n equal to a lower randomness.? Because Math.floor() rounds numbers down? 3.323=3 0.389=0
I saw on this website, that this algorithm had a negative bias, across all numbers, but I didn’t really understood :sweat_smile:

thank you as well!! I’m going to try that out right away!

If n === 1, all possible outcomes of Math.random() would be rounded to 0. This is completely non-random and Math.random() makes no sense, right?
If n === 2, 50% of all possible outcomes of Math.random() would be rounded to 0 and another 50% to 1 - we started to increase randomness slightly
… and so on, until n === 1e+17, when further increase no longer would increase randomness (as Math.random() gives 16 digits after decimal point.

1 Like

just wanted to share that it’s working BEAUTIFULLY!

//fischer-yates to shuffle the board 

function shuffle() {
    var array = Array.from(document.querySelectorAll(".karten"));
    var remainingElements = array.length;
    var temporaryValue, randomIndex;

    // While there remain elements to shuffle...
    while (0 !== remainingElements) {
        // Pick a remaining element...
        randomIndex = Math.floor(Math.random() * remainingElements);
        // removing divs from DOM while shuffling :)
        document.querySelectorAll(".karten")[0].remove();

        remainingElements -= 1;

        // And swap it with the current element.
        temporaryValue = array[remainingElements];
        array[remainingElements] = array[randomIndex];
        array[randomIndex] = temporaryValue;
    }
    //add shuffled Elements to DOM (.board is parent of .karten)
    for (var i = 0; i < array.length;i++) {
        document.querySelector(".board").appendChild(array[i]);
    }
}
//sources
//https://stackoverflow.com/questions/2450954/how-to-randomize-shuffle-a-javascript-array
//https://stackoverflow.com/questions/13427287/shuffle-all-divs-with-the-same-class
//http://forum.freecodecamp.org/t/custom-bad-shuffling-in-javascript-troubleshoot/327115/

i think I have to research into that matter a bit more or watch some videos about randomness :sweat_smile: