2

var arr = [1, 2, 3, 4];
finalarr = [];
for (i = 0; i <= 5; i++) {
  arr.sort(function(a, b) {
    return 0.5 - Math.random();
  });
  finalarr.push(arr);
}
/*once it randomizes that first array, it keeps repeating it. i dont want 
that i want it to reshuffle the array everytime i run that loop*/
console.log(finalarr);

It randomizes the array only once and keeps repeating it

  • 1
    Does this answer your question? [How to randomize (shuffle) a JavaScript array?](https://stackoverflow.com/questions/2450954/how-to-randomize-shuffle-a-javascript-array) – Jaydeep Jan 03 '20 at 05:51
  • 2
    You're pushing a reference of an array, so each time you shuffle your array it will shuffle in your `finalarr`. You can make a copy of the array and then push it `finalarr.push([...arr].sort...)`. Also, that shuffling method is known not to be very random. – Nick Parsons Jan 03 '20 at 05:51
  • *"...once it randomizes that first array, it keeps repeating it"* How many times and in what type of data structure? Nested arrays are hard to make useful if you do not have a full grasp of a standard array. – zer00ne Jan 03 '20 at 06:33

5 Answers5

2

Edit

The second demo is Demo 1 modified to accept two parameters:

@Params: array [Array]...: The array to shuffle
        repeat [Number]..: The number of new randomized arrays to be returned

@Return: An array of arrays (aka "two-dimensional array") 


As mentioned by Nick Parsons, you are using a reference to the array plus your result is a full array in which you are adding to an empty array (ex. [[4, 3, 2, 1]]) a more practical return would be just an array with the same elements as the original array but in a random order ([2, 4, 1, 3]).

The following demo:

  1. Uses the most effective way to shuffle an array: Fisher–Yates algorithm.

  2. Accepts a standard array and clones it by the spread operator [...array]

  3. The shuffle() function is called three separate times and returns a new array with a randomized order.

Note: There's an optional utility function that just displays console logs nicer. It is not a requirement.

Demo 1

let array = [1, 2, 3, 'A', 'B', 'C'];

const shuffle = ([...array]) => {
  let i = 0;
  let j = 0;
  let temp = null;

  for (i = array.length - 1; i > 0; i -= 1) {
    j = Math.floor(Math.random() * (i + 1));
    temp = array[i];
    array[i] = array[j];
    array[j] = temp;
  }
  return array;
}

const log = data => console.log(JSON.stringify(data));

log(shuffle(array));
log(shuffle(array));
log(shuffle(array));

Demo 2

let array = [1, 2, 3, 'A', 'B', 'C'];

const shuffle = (array, repeat = 1) => {
  let result = [];
  for (let r = repeat; r > 0; r -= 1) {
    let clone = [...array];
    for (let i = clone.length - 1; i > 0; i -= 1) {
      let s = Math.floor(Math.random() * (i + 1));
      let temp = clone[i];
      clone[i] = clone[s];
      clone[s] = temp;
    }
    result.push(clone);
  }
  return result;
}

const log = data => console.log(JSON.stringify(data));


log(shuffle(array));
log(shuffle(array, 5));
// .flat() is invoked on the return array to provide a single array
log(shuffle(array, 5).flat());
zer00ne
  • 41,936
  • 6
  • 41
  • 68
1

You just need to dereference the arr before pushing. Any of following three would work.

var arr = [1, 2, 3, 4];
finalarr = [];
for (i = 0; i <= 5; i++) {
  arr.sort(function(a, b) {
    return 0.5 - Math.random();
  });
  finalarr.push(Object.assign({},arr));
}
console.log(finalarr);

var arr = [1, 2, 3, 4];
finalarr = [];
for (i = 0; i <= 5; i++) {
  arr.sort(function(a, b) {
    return 0.5 - Math.random();
  });
  finalarr.push({...arr});
}
console.log(finalarr);

var arr = [1, 2, 3, 4];
finalarr = [];
for (i = 0; i <= 5; i++) {
  arr.sort(function(a, b) {
    return 0.5 - Math.random();
  });
  finalarr.push(JSON.parse(JSON.stringify(arr)));
}
console.log(finalarr);
Geetanjali
  • 458
  • 3
  • 13
1

Attach an array literal to the sort function, and push the result to the final array.

let finalarr = []

for (i = 0; i <= 5; i++) {
  let arr = [1, 2, 3, 4].sort(function(a, b) {
    return 0.5 - Math.random()
  })
  finalarr.push(arr)
}

console.log(finalarr)
symlink
  • 11,984
  • 7
  • 29
  • 50
1

The problem here is that you're adding a reference to the same array for each index. They're not all their own arrays- they're all the exact same one. Imagine there are two newscasters, each reporting on the same story. If the story changes, both newscasters will tell you the same update. That's what these arrays are doing. When you say something like arr1 = arr2, you're just saying that arr1 is now a newscaster for the same story/value- so changing the value associated with one of them changes both of them, and shuffling one of them shuffles both of them. To change this, you need to clone the array before assigning it to a new variable.

Change:

finalarr.push(arr);

to:

finalarr.push(arr.slice(0));

Using .slice(0) on the array is a method to clone a shallow copy of the array (which will be sufficient for your code) so each one is actually its own value. Run this new version of your code here:

var arr = [1, 2, 3, 4];
finalarr = [];
for (i = 0; i <= 5; i++) {
  arr.sort(function(a, b) {
    return 0.5 - Math.random();
  });
  finalarr.push(arr.slice(0));
}
console.log(finalarr);

Personally, I choose to use randojs.com to grab shuffled arrays. It grabs a new, independent array each time you call randoSequence, so no funny business to worry about with references. Your code would look like this with randojs:

var finalarr = [];
for (var i = 0; i <= 5; i++) finalarr.push(randoSequence(1, 4));
console.log(finalarr);
<script src="https://randojs.com/1.0.0.js"></script>
Aaron Plocharczyk
  • 2,776
  • 2
  • 7
  • 15
0

Yes, you can use javascript array shuffle function to randomly shuffle your array.

like in your code,

var arr=[1,2,3,4]
finalarr = [];
var shuffle_arr=shuffle(arr);
finalarr.push(shuffle_arr);

just use the shuffle function.

Konrad
  • 17,740
  • 16
  • 106
  • 167
Jay Desani
  • 11
  • 2