2

I want to know how to shuffle an array and return a NEW array. So far I have seen this solution in Stack Overflow:

How to randomize (shuffle) a JavaScript array?

This solution works perfectly in returning the same array shuffled, but I don't really understand why. Can anyone explain this and help me revise it so that it returns a new array?

Thanks!

Community
  • 1
  • 1
lnamba
  • 1,611
  • 3
  • 16
  • 25

3 Answers3

4

The easiest way I know of to create a copy of an array is using:

var newArray = [].concat(originalArray);

You could perform that in the first line of most of the solutions on the linked answer and you would be getting a new array back with the original untouched. Here is a modified version of the top rated answer on the linked question:

function shuffle(originalArray) {
  var array = [].concat(originalArray);
  var currentIndex = array.length, temporaryValue, randomIndex;

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

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

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

  return array;
}
Rob M.
  • 33,381
  • 6
  • 50
  • 46
  • 1
    [Clone Arrays with JavaScript](https://davidwalsh.name/javascript-clone-array) suggests `var array = originalArray.slice(0);`. – Ouroborus Mar 23 '17 at 01:08
  • @Ouroborus yes that is another way of cloning arrays. I don't think you should modify the `Array` prototype though, as he suggests. Also, `concat` appears to be significantly faster than `slice`: https://jsperf.com/test-slice-vs-concat/1 – Rob M. Mar 23 '17 at 01:17
  • 1
    Actually, it's only significantly faster in Chrome, in Safari they are about equal and Firefox `slice` is significantly faster. Oh browsers... :P – Rob M. Mar 23 '17 at 01:19
  • Great thank you Rob! That seemed so simple, so I think I was just making it more complicated than it was. Thanks again! – lnamba Mar 23 '17 at 01:32
2

Maybe useful for you

var original = ['a', 'b', 'c', 'd', 'e', 'f', 'g'];
var copy = [].concat(original);
copy.sort(function(){
  return 0.5 - Math.random();
});
console.log(copy);
Valentin Podkamennyi
  • 6,855
  • 4
  • 25
  • 43
dipenparmar12
  • 2,318
  • 1
  • 25
  • 34
0

If you want to use 3rd party library, Lodash is very good for this.

Just use _.shuffle(), to get new array.

Ouroborus
  • 14,339
  • 1
  • 33
  • 57
raju
  • 5,758
  • 17
  • 61
  • 136