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
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
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
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 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.
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
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.
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/