Photo by Leio McLaren (@leiomclaren) on Unsplash
Photo by Gautier Salles on Unsplash
Using Math functions
The built-in Math functions Math.min() and Math.max() do exactly what one would expect ? they return the smallest or largest number of the list of numbers passed to them as arguments.
Since Math.min() and Math.max() both expect the numbers as arguments, and not an array, they do not seem at first choice to be good options for getting the smallest or largest number from an array:
On first glance, it looks like we need a different approach. Thankfully, using the ES6 feature spread syntax (?) makes arrays easily compatible with these functions, as I explain in the next section.
Photo by Quino Al on Unsplash
Math.min(?array) and Math.max(?array)
?[The spread] operator causes the values in the array to be expanded, or ?spread,? into the function?s arguments.? ? Joel Lovera on jstips.co
Using the three magic dots (?) makes it easy to call any function expecting arguments, like these built-in Math functions, using an array.
Photo by Joe Cook on Unsplash
Without the spread operator
Here is the current browser compatibility chart for the spread operator:
Calling the function Function.prototype.apply() will have the same effect as the spread syntax:
Note that the first argument to .apply() is the target for this, which in this case does not matter, so I passed in null as the first argument.
Photo by Mathias Elle on Unsplash
Sorting the list numerically
For example, the code .sort((a,b) => a-b) will sort numbers in ascending order from smallest to largest.
Once sorted, the first number will be the min and the last the max:
Photo by Phil Reid on Unsplash
Using a for loop or .reduce()
Either a for loop or the Array.prototype.reduce() method can be used to find the minimum and maximum numbers in an array:
Brandon Morelli reported previously on Codeburst.io that these methods may be fastest, so I compare the performance of all 5 methods next.
Photo by Stphane Juban on Unsplash
Wow! For some reason the spread operator is half the speed of the other methods. Since using .apply() works quickly, it appears using the spread operator over 40 arguments really slows things down.
It appears to not be the fault of the Math.min() or Math.max() functions themselves per se, since a for loop that avoids those functions has basically the same performance for this test case of 40 random items.
Photo by Quentin Rey on Unsplash
A second look: 4000 items
I updated the test suite to generate a 4000 item array to examine if it changes the comparative performance of finding the min and max.
Indeed, it does, with the spread operator being 92% slower:
This shows that the performance drop is associated with the spread operator in a way that scales with the number of arguments being spread.
With very large arrays, the for loop is fastest by far, with .apply() coming in second, .sort() and .reduce() tied for third, and spread dead last.
It is worth noting that using Babel to compile the code may restore some performance for large and very large arrays, since it will transpile the spread operator to the .apply() syntax using babel-plugin-transform-spread.
Photo by Andy Brunner on Unsplash
A third look: Just 3 items
However, don?t throw the spread operator out just quite yet ? there is no performance difference when we drop down to 3 items:
So, for day-to-day use, the spread operator works brilliantly.
Meanwhile, the iterative for loop is 3% slower than the spread operator when only dealing with an array of only 3 items.
Photo by Joshua Earle on Unsplash
However, when dealing with large arrays of 40 items or more, using the spread operator has significantly worse performance compared to other methods of finding the minimum and maximum.
What to do for larger arrays
For large arrays, using Math.min.apply(null,array) and Math.max.apply(null,array) restores the lost performance from the spread operator and allows one to continue to use the built-in Math functions.
Finally, with very large arrays of 4000 items or more, a for loop is the fastest method by far, so keep that in mind. It may be ugly, but it works.
Now go find some minimums and maximums! ?
Photo by Hannah Reding on Unsplash
- GeeksforGeeks explores using .map() and .reduce() to find min/max:
Given an array of objects and the task is to get the maximum and minimum value from the array of objects. There are a?
- Dan Vega finds the maximum id in an array of objects on his blog:
I was recently putting together a tutorial for some students and I came across an issue that I am sure we have all come?
- The site w3resource has a visual tutorial on finding a minimum:
- The library d3-array includes the useful .minIndex() & .maxIndex(), although a for loop will likely be faster for very large arrays:
Array manipulation, ordering, searching, summarizing, etc. – d3/d3-array
- Brandon Morelli found for loops are fast in his article on codeburst.io:
Three potential solutions. But which is fastest?
- Previous research on very large arrays of 250,000 items published on the Microsoft devblog showed that for loops are the fastest method by far:
Today’s Little Program isn’t even a program. It’s just a function. The problem statement is as follows: Given a?
Photo by Rachel Cook on Unsplash