The code below works for a normal array but not with an array with object does anybody knows how to do this?
If you need to shuffle a collection of element nodes (in the DOM), convert it to an array first:
var wrapper = document.getElementById('someid');
var array = Array.prototype.slice.call(wrapper.children);
Shuffling a HTMLCollection object (as returned by children
) directly doesn't work even if you can iterate the collection with a for loop. This stumbled me for a while.
Try sorting like this snippet:
console.log( [
{ some: 1 },
{ some: 2 },
{ some: 3 },
{ some: 4 },
{ some: 5 },
{ some: 6 },
{ some: 7 },
]
.sort( () => Math.random() - 0.5) );
In reponse to Martin Omanders comment: here's a shuffle method according to the Fisher-Yates algorithm
for (let i=0; i<20; i+=1) {
console.log(JSON.stringify(shuffleFisherYates([0,1,2,3,4,5,6,7,8,9])));
}
function shuffleFisherYates(array) {
let i = array.length;
while (i--) {
const ri = Math.floor(Math.random() * (i + 1));
[array[i], array[ri]] = [array[ri], array[i]];
}
return array;
}
Which may be condensed to a one liner (note: this one liner will not compile in the Google Closure Compiler with level advanced):
const shuffle = array =>
[...Array(array.length)]
.map((...args) => Math.floor(Math.random() * (args[1] + 1)))
.reduce( (a, rv, i) => ([a[i], a[rv]] = [a[rv], a[i]]) && a, array);
for (let i=0; i<100; i+=1)
console.log(JSON.stringify(shuffle([0,1,2,3,4,5,6,7,8,9])));
Here is one more example based on lodash _.shuffle.
const array = [
{ some: 1 },
{ some: 2 },
{ some: 3 },
{ some: 4 },
{ some: 5 },
{ some: 6 },
{ some: 7 },
];
console.log(_.shuffle(array));
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>