DEV Community

Jason F
Jason F

Posted on

Adventures with JavaScript Arrays: Random Numbers Array

The JavaScript array is an ubiquitous data structure, thus I'd like to spend some time to get more familiar/reacquainted with the Array object. I'll share my knowledge with you in the form of blog posts.

In this post I'll create a function that returns an array of random whole numbers.

Let's get started!



function randomNumbersArray(length = 10) {
    // return array of random numbers between 1 and 100
    // if length parameter is not provided, length is set to 10
}


Enter fullscreen mode Exit fullscreen mode

We know that we want to create an array of random whole numbers between 1 and 100 with either a specified length or 10. Let's first discuss the Array constructor.

Calling Array constructor with single number argument

With JavaScript's Array constructor you are able to call it with a single number argument. If you do this, an array will be created with the length of the number that is received. Each element will be undefined.

Image description

In the example above, I am calling the Array constructor with an argument of 10. As you can see, the length property is set to 10.

Array.from()

Array.from is a static method on the JavaScript Array object which will create a new array from an iterable/array-like object.

The first parameter of Array.from is an object. So we could do something like this:

Image description

We call Array.from with a string, which is an iterable object, and an array is created from that value.

Array.from has an optional second parameter which is a mapping function.

Image description

In the example above, we are using the mapping function to capitalize each letter in the first argument.

Putting it all together

Let's now take what we know about the JavaScript Array and create the randomNumbersArray function.



function randomNumbersArray(length = 10) {
  return Array.from(Array(length), () => Math.floor(Math.random() * 100) + 1);
}


Enter fullscreen mode Exit fullscreen mode

Here's an example showing the output.

Image description

We are calling Array.from and passing in an array with a length of the value of the length argument that is created using the Array constructor as the first param, and we are passing in a mapping function that creates a random whole number between 1 and 100 for each element of the array as the second param.

We now have a function that creates an array, with a length of 10, unless a length argument is provided, of whole numbers between 1 and 100.

Conclusion

Of course there are multiple ways to create an array of random numbers in JavaScript. I thought this approach was interesting as it uses the Array object's constructor and the from static method. Thanks for reading! Until next time.

Top comments (6)

Collapse
 
tracygjg profile image
Tracy Gilmore

Hi Jason,

I enjoyed your post and it set me thinking.

It has been a long time since I wrote a conventional JS for loop to traverse the elements of an array. The introduction of the map, filter and reduce (et al) Array methods have virtually eliminated the need.

For a while I have been wondering if I could do something similar to remove the other major use of for loops, that being to perform a group of instructions (statement block or call-back function) a fixed number of times.

After several iterations I finally devised a mechanism I was happy with until I read your post. I have now revised my adhocArray function to use the (seldom used) Array constructor.

The latest implementation looks like this.

function adhocArray(length = 1, transform = _ => _) {
  return [...Array(length)].map((_, i) => transform(i));
}
Enter fullscreen mode Exit fullscreen mode

I found using the spread operator ... in combination with the map method, slightly more effective than the Array.from method.

This would enable randomNumbersArray to be implemented as follows:

function randomNumbersArray(length = 10) {
  return adhocArray(length, () => Math.floor(Math.random() * 100) + 1);
}
Enter fullscreen mode Exit fullscreen mode

or, using an arrow function;

const randomNumbersArray = (length = 10) =>
  adhocArray(length, () => Math.floor(Math.random() * 100) + 1);
Enter fullscreen mode Exit fullscreen mode

There may appear to be little/no benefit in using one over the other but adhocArray is a more general purpose function that can be applied to many more use cases.

You could combined the two to form:

function randomNumbersArray(length = 10) {
  return [...Array(length)].map(() => Math.floor(Math.random() * 100) + 1);
}
Enter fullscreen mode Exit fullscreen mode

Whatever approach, there is also an alternative to using Math.floor you might want to know is ~~. This would change Math.floor(Math.random() * 100) + 1 into ~~(Math.random() * 100) + 1.

Keep posting, keep learning

Collapse
 
juniordevforlife profile image
Jason F

Thank you for sharing. I find the double NOT bitwise operator interesting. I'd be curious to know the impact on performance when choosing ~~ over Math.floor, as well as any caveats or gotchas.

Collapse
 
jonrandy profile image
Jon Randy πŸŽ–οΈ • Edited

~~ is faster than Math.floor - but it doesn't do the same thing. It just removes the decimal part instead of rounding down to the nearest integer - a subtle difference, but it can mess you up when dealing with negative numbers:

Math.floor(1.1)  // 1
~~1.1  // 1

Math.floor(-1.1)  // -2
~~-1.1 // -1
Enter fullscreen mode Exit fullscreen mode
Thread Thread
 
tracygjg profile image
Tracy Gilmore

Thank you Jon, for the clarifying comment. You are absolutely correct that any shortcut like ~~ needs to be taken with care. In this context (I tested this before advising) rounding down via truncation is exactly what is required. Best regards.

Collapse
 
jonrandy profile image
Jon Randy πŸŽ–οΈ • Edited

No need to pass in an actual array:

const randomNumbersArray = (length=10) =>
   Array.from({length}, () => ~~(Math.random() * 100) + 1)
Enter fullscreen mode Exit fullscreen mode
Collapse
 
juniordevforlife profile image
Jason F

Thanks for this @jonrandy!