Sorting an Array in Random Order

18,283

Solution 1

You used

var as = ["max","jack","sam"];  
var s = as.sort(func);  

function func(a, b) {  
  return 0.5 - Math.random();
}  

console.log(s);

And here the most important thing is as.sort(func).
func(a,b) will return value in range of [-0.5,0.5].

Because this function return 0.5 - Math.random() and Math.random() will return the float value which is in range of [0,1].
So that your func will return value in range of [-0.5,0.5].

And this mean that sort order will be set increase or decrease. this is random. So your result will be random

var as = ["max","jack","sam"];  
var s = as.sort(func);  

function func(a, b) {  
  return Math.random();
}  

console.log(s);

var as = ["max","jack","sam"];  
var s = as.sort(func);  

function func(a, b) {  
  return 0 - Math.random();
}  

console.log(s);

var as = ["max","jack","sam"];  
var s = as.sort(func);  

function func(a, b) {  
  return 0.5 - Math.random();
}  

console.log(s);

Solution 2

Math.random() returns a number between 0 and 1 (exclusive). We're using 0.5 because it is the mean value.

Array.sort() sorts the parameters based on the return value. So, 0.5 - Math.random() will yield either positive or negative value with equal probability. Hence, it will sort the parameters randomly.

How it really works

  • If the return value of Array.sort() is positive, then the index of the first parameter will be higher than that of the second.
  • If it is negative, then the index of the second parameter will be higher than that of the first.
  • And, if it is 0, then do nothing.

Solution 3

Math.random() return random value between 0 to 1 (0 is included but 1 is excluded). So 0.5 act as mid point. If use use value like greater than 1 or less 0 than it will always be either true or false. So for this reason 0.5 is used.

You can read more here about Math.random()

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random

Let's understand it bit more with examples

var as = ["max","jack","sam"];  
var s = as.sort(func);  

function func(a, b) {  
  return 0.5 - Math.random();
}  

console.log(s);

This is what you get when you use value greater than 1

var as = ["max","jack","sam"];  
var s = as.sort(func);  

function func(a, b) {  
  return 1 - Math.random();
}  

console.log(s);

This is what happens when you use value less than 0

var as = ["max","jack","sam"];  
var s = as.sort(func);  

function func(a, b) {  
  return -1 - Math.random();
}  

console.log(s);

P.S :-

  1. Try printing output from all the above condition you will see that last two condition will always return either true or false from function. so you will not get a random sorting.

  2. Now talk about any value from 0 to 0.99 you can use any value but 0.5 will serve your purpose best.Because it's a middle point you're most likely to get best answer.

Solution 4

If you just want to nudge the elements near their starting positions in a random way, sure, use sort with random, but in most cases, that's not what you want. You want to thoroughly shuffle an array, completely randomize the position of every element. And for that random in the built-in sort function is a terrible practice, because it is biased towards the initial state, meaning that the elements in the "shuffled" array will tend to stay near their positions (those that were near the beginning have the high probability of staying near the beginning, etc...). The bigger the size the array grows, the less it gets shuffled.

Here is the proof: Is it correct to use JavaScript Array.sort() method for shuffling?

And here is the function for shuffling arrays I use most of the time. It thoroughly randomizes the position of every element.

function shuffle(arr) { // randomly rearanges the items in an array
  const result = [];
  for (let i = arr.length-1; i >= 0; i--) {
    // picks an integer between 0 and i:
    const r = Math.floor(Math.random()*(i+1));   // NOTE: use a better RNG if cryptographic security is needed
    // inserts the arr[i] element in the r-th free space in the shuffled array:
    for(let j = 0, k = 0; j <= arr.length-1; j++) {
      if(result[j] === undefined) {
        if(k === r) {
          result[j] = arr[i];    // NOTE: if array contains objects, this doesn't clone them! Use a better clone function instead, if that is needed. 
          break;
        }
        k++;
      }
    }
  }
  return result;
}

Solution 5

Math.random returns a number between 0 and 1.

Sorting function use the return value x as the following :

  • x == 0 : Same value, can order "how it wants"

  • x < 0 : the first object is less than the second one, therefore its index in the sorted array will be less than the other's

  • x > 0 same as x < 0 but the other way around

Since Math.random returns a number between 0 and 1 and we want to also get negative numbers, we must subtract some value. Here 0.5 - Math.random() would give a number between 0.5 and -0.5

Share:
18,283
Amine El were
Author by

Amine El were

Updated on June 06, 2022

Comments

  • Amine El were
    Amine El were almost 2 years

    I'm trying to understand how sorting an array in random order works. So, I found the following code:

    var as = ["max","jack","sam"];  
    var s = as.sort(func);  
    
    function func(a, b) {  
      return 0.5 - Math.random();
    }  
    
    console.log(s);

    my main question is why they use 0.5 not another number? and how it really works

    • KolaCaine
      KolaCaine over 5 years
      Why you passed func into your sort() function for sorting an array of string ?
    • George
      George over 5 years
      @KolaCaine Becuase .sort take a sort function?
    • KolaCaine
      KolaCaine over 5 years
      Yes, you can passed a callback function. But what do you want to achieve ?
    • sertsedat
      sertsedat over 5 years
      terminologically it's not sorting but shuffling using sort function
    • sertsedat
      sertsedat over 5 years
      also please refer to the answer from the question @ponury-kostek linked: stackoverflow.com/a/18650169/3729695
    • MSalters
      MSalters over 5 years
      This is a bad idea - the sort predicate should be consistent. If for whatever reason you compare a and b twice, the result should be the same. And in general, it should also consistent. (So a<b and b<c imply a<c, or a>b and b>c imply a>c - the choice of order is independent from the need for consistency)
    • Bergi
      Bergi over 5 years
    • wizzwizz4
      wizzwizz4 over 5 years
      @ponury-kostek Personally, I think that this one's closer, since the question's asking how this particular one works, not how it should be done.
  • BallpointBen
    BallpointBen over 5 years
    Crucially, a value of 0.5 makes the probability that one element is evaluated to be less than another exactly 1/2, which makes the random sort unbiased with respect to the initial order of the list.
  • Bergi
    Bergi over 5 years
  • BallpointBen
    BallpointBen over 5 years
    Thanks @Bergi, I'm leaving my comment anyway so that others can see the error
  • PKPrabu
    PKPrabu almost 3 years
    Actually, Math.random() method will return 0 to less than 1. Not 0 to 1. developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…