DEV Community

Discussion on: Why I don't like JavaScript

Collapse
 
avalander profile image
Avalander

Not really, since the intent of the original implementation is to generate a sequence of unique elements, and your implementation can yield duplicated values.

A better approach would be to just generate the sequence in order and shuffle it:

const range = (from, to) => {
  const data = []
  for (let i = from; i <= to; i++) data.push(i)
  return data
}

const randSeq = (min, max) => {
  const data = range(min, max)
  data.sort(() => Math.random() - 0.5)
  return data
}

The data.sort trick doesn't produce a lot of variations, though. A better way is to generate the sorted array and pick elements from a random index and add them to a new array.

const randSeq2 = (min, max) => {
  const data = range(min, max)
  const result = []
  while (data.length > 0) {
    const i = randInt(0, data.length - 1)
    result.push(data[i])
    data.splice(i, 1)
  }
  return result
}

At this point the implementation is equally verbose to the original, so ¯\_(ツ)_/¯. But it avoids unnecessary iterations when duplicated values are generated.

Collapse
 
stephenramthun profile image
Stephen Ramthun

Nice catch, thanks! Didn't realise that the list had to be unique. Could you explain what you mean by .sort() not producing a lot of variations?

Thread Thread
 
avalander profile image
Avalander • Edited

[].sort(() => Math.random() - 0.5) tends to not displace elements in the array a lot. An element might be moved a few positions forward or backward, but it will generally stay close to its original position. Therefore, when used to shuffle an array, the result will be more similar to the original array than with other algorithms.

As an example, here's the output of three runs with randSeq and three runs with randSeq2:

# randSeq
[ 1, 3, 4, 5, 9, 7, 6, 8, 2, 10 ]
[ 7, 1, 2, 3, 6, 8, 4, 5, 9, 10 ]
[ 2, 3, 1, 4, 6, 9, 8, 5, 7, 10 ]

# randSeq2
[ 5, 1, 7, 10, 4, 6, 3, 9, 8, 2 ]
[ 7, 1, 6, 9, 5, 8, 3, 4, 10, 2 ]
[ 2, 6, 4, 10, 9, 8, 5, 3, 1, 7 ]

You can notice that with the randSeq the array is less shuffled than with randSeq2 and the elements show a clear tendency to be larger the further back they are in the array.

Thread Thread
 
stephenramthun profile image
Stephen Ramthun

Makes sense. Thanks!