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!

2
  • You want it to not modify your original array but just return a new one (a copy)? Commented Mar 23, 2017 at 0:39
  • You'll want to read en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle Commented Mar 23, 2017 at 1:23

4 Answers 4

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

4 Comments

Clone Arrays with JavaScript suggests var array = originalArray.slice(0);.
@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: jsperf.com/test-slice-vs-concat/1
Actually, it's only significantly faster in Chrome, in Safari they are about equal and Firefox slice is significantly faster. Oh browsers... :P
Great thank you Rob! That seemed so simple, so I think I was just making it more complicated than it was. Thanks again!
3

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);

Comments

0

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

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

1 Comment

This answer doesn't explain anything.
0

const shuffle = (array) => { const mutatedArray = [...array]; for (let i = mutatedArray.length - 1; i > 0; i--) { const j = Math.floor(Math.random() * (i + 1)); [mutatedArray[i], mutatedArray[j]] = [mutatedArray[j], mutatedArray[i]]; } return mutatedArray; }; console.log(shuffle(["a", "b", "c", "d"]))

Powered by Fisher-Yates algorithm.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.