Obtain smallest value from array in Javascript?

220,002

Solution 1

Jon Resig illustrated in this article how this could be achieved by extending the Array prototype and invoking the underlying Math.min method which unfortunately doesn't take an array but a variable number of arguments:

Array.min = function( array ){
    return Math.min.apply( Math, array );
};

and then:

var minimum = Array.min(array);

Solution 2

The tersest expressive code to find the minimum value is probably rest parameters:

const arr = [14, 58, 20, 77, 66, 82, 42, 67, 42, 4]
const min = Math.min(...arr)
console.log(min)

Rest parameters are essentially a convenient shorthand for Function.prototype.apply when you don't need to change the function's context:

var arr = [14, 58, 20, 77, 66, 82, 42, 67, 42, 4]
var min = Math.min.apply(Math, arr)
console.log(min)

This is also a great use case for Array.prototype.reduce:

const arr = [14, 58, 20, 77, 66, 82, 42, 67, 42, 4]
const min = arr.reduce((a, b) => Math.min(a, b))
console.log(min)

It may be tempting to pass Math.min directly to reduce, however the callback receives additional parameters:

callback (accumulator, currentValue, currentIndex, array)

In this particular case it may be a bit verbose. reduce is particularly useful when you have a collection of complex data that you want to aggregate into a single value:

const arr = [{name: 'Location 1', distance: 14}, {name: 'Location 2', distance: 58}, {name: 'Location 3', distance: 20}, {name: 'Location 4', distance: 77}, {name: 'Location 5', distance: 66}, {name: 'Location 6', distance: 82}, {name: 'Location 7', distance: 42}, {name: 'Location 8', distance: 67}, {name: 'Location 9', distance: 42}, {name: 'Location 10', distance: 4}]
const closest = arr.reduce(
  (acc, loc) =>
    acc.distance < loc.distance
      ? acc
      : loc
)
console.log(closest)

And of course you can always use classic iteration:

var arr,
  i,
  l,
  min

arr = [14, 58, 20, 77, 66, 82, 42, 67, 42, 4]
min = Number.POSITIVE_INFINITY
for (i = 0, l = arr.length; i < l; i++) {
  min = Math.min(min, arr[i])
}
console.log(min)

...but even classic iteration can get a modern makeover:

const arr = [14, 58, 20, 77, 66, 82, 42, 67, 42, 4]
let min = Number.POSITIVE_INFINITY
for (const value of arr) {
  min = Math.min(min, value)
}
console.log(min)

Solution 3

I find that the easiest way to return the smallest value of an array is to use the Spread Operator on Math.min() function.

return Math.min(...justPrices);
//returns 1.5 on example given 

The page on MDN helps to understand it better: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/min

A little extra: This also works on Math.max() function

return Math.max(...justPrices); //returns 9.9 on example given.

Hope this helps!

Solution 4

Update: use Darin's / John Resig answer, just keep in mind that you dont need to specifiy thisArg for min, so Math.min.apply(null, arr) will work just fine.


or you can just sort the array and get value #1: [2,6,7,4,1].sort()[0]

[!] But without supplying custom number sorting function, this will only work in one, very limited case: positive numbers less than 10. See how it would break:

var a = ['', -0.1, -2, -Infinity, Infinity, 0, 0.01, 2, 2.0, 2.01, 11, 1, 1e-10, NaN];

// correct: 
a.sort( function (a,b) { return a === b ? 0 : a < b ? -1: 1} );
//Array [NaN, -Infinity, -2, -0.1, 0, "", 1e-10, 0.01, 1, 2, 2, 2.01, 11, Infinity]

// incorrect:
a.sort();
//Array ["", -0.1, -2, -Infinity, 0, 0.01, 1, 11, 1e-10, 2, 2, 2.01, Infinity, NaN]

And, also, array is changed in-place, which might not be what you want.

Solution 5

Imagine you have this array:

var arr = [1, 2, 3];

ES6 way:

var min = Math.min(...arr); //min=1

ES5 way:

var min = Math.min.apply(null, arr); //min=1

If you using D3.js, there is a handy function which does the same, but will ignore undefined values and also check the natural order:

d3.max(array[, accessor])

Returns the maximum value in the given array using natural order. If the array is empty, returns undefined. An optional accessor function may be specified, which is equivalent to calling array.map(accessor) before computing the maximum value.

Unlike the built-in Math.max, this method ignores undefined values; this is useful for ignoring missing data. In addition, elements are compared using natural order rather than numeric order. For example, the maximum of the strings [“20”, “3”] is “3”, while the maximum of the numbers [20, 3] is 20.

And this is the source code for D3 v4:

export default function(values, valueof) {
  var n = values.length,
      i = -1,
      value,
      max;

  if (valueof == null) {
    while (++i < n) { // Find the first comparable value.
      if ((value = values[i]) != null && value >= value) {
        max = value;
        while (++i < n) { // Compare the remaining values.
          if ((value = values[i]) != null && value > max) {
            max = value;
          }
        }
      }
    }
  }

  else {
    while (++i < n) { // Find the first comparable value.
      if ((value = valueof(values[i], i, values)) != null && value >= value) {
        max = value;
        while (++i < n) { // Compare the remaining values.
          if ((value = valueof(values[i], i, values)) != null && value > max) {
            max = value;
          }
        }
      }
    }
  }

  return max;
}
Share:
220,002
lisovaccaro
Author by

lisovaccaro

Updated on May 19, 2021

Comments

  • lisovaccaro
    lisovaccaro almost 3 years

    Array justPrices has values such as:

    [0] = 1.5
    [1] = 4.5
    [2] = 9.9.
    

    How do I return the smallest value in the array?

  • Marek Sebera
    Marek Sebera over 12 years
    Is there any reason, why you don't recommend prototyping?
  • Davsket
    Davsket over 12 years
    or [2,6,7,4,1].sort()[0] if you want to preserve the array objects
  • Darin Dimitrov
    Darin Dimitrov over 12 years
    @MarekSebera, I didn't write the article, I just linked to it. Ask John Resig why.
  • zzzzBov
    zzzzBov over 12 years
    @MarekSebera, while I like to extend the Array.prototype myself, I recommend treading with care. for..in loops can pick up functions in addition to the numbered indices, and a careless programmer could easily break code.
  • Davsket
    Davsket over 12 years
    I find more cool @c69 solution adapted to the prototype: Array.prototype.min = function(){return this.sort()[0]}
  • chuckj
    chuckj over 12 years
    @Davsket Math.min is O(N) where sort is O(N log N). It is cute but slower; much slower on large arrays.
  • zzzzBov
    zzzzBov almost 11 years
    @Davsket, Array.prototype.sort will impact the original array object by changing all the indices, whereas a valid Array.prototype.min function would not have such side effects.
  • Davsket
    Davsket almost 11 years
    @zzzzBov yeah, I know, but it's interesting, an even slower but safer solution could use slice before sorting, but is totally obvious that using Math.min is the better way. In fact... I up-voted this that day ;)
  • Stefan Monov
    Stefan Monov over 7 years
    "positive numbers less than 10" - why? Does it use string comparison by default?
  • jiggzson
    jiggzson over 7 years
    Out of curiosity, what's the benefit of doing this over calling Math.min directly?
  • Libu Mathew
    Libu Mathew over 7 years
    @jiggzson See Darin Dimitrov description "Math.min method which unfortunately doesn't take an array but a variable number of arguments". This solutions work well with both array and variable number of arguments.
  • jiggzson
    jiggzson over 7 years
    I was referring to your prior example. I noticed that you edited to detect for an array. I imagine that was your original intention. Thanks.
  • Spets
    Spets over 7 years
    best answer here!
  • jacktrade
    jacktrade about 7 years
    very smart solution!
  • Sten Muchow
    Sten Muchow almost 7 years
    bang on... answer tho is for min not max ;)
  • Mark Carpenter Jr
    Mark Carpenter Jr over 6 years
    Maybe the question is wrong and it's for max... twice it's been answered and twice it's been for max... just sayin` ¯\_(ツ)_/¯
  • emilsteen
    emilsteen almost 4 years
    This is terrible code. It only works if the min value is first, otherwise you get IndexOutOfRangeException. And all the "min = min" is probably a not yet invented anti-pattern.
  • WebDevBooster
    WebDevBooster over 3 years
    The first part of the explanation (not the code) in this answer is confusing/incorrect. The claim "Rest parameters are essentially a convenient shorthand for Function.prototype.apply" should be replaced with: The destructuring assignment syntax (...arr) is a JavaScript expression that makes it possible to unpack values from arrays (or properties from objects) into distinct variables. So, Math.min(...arr) is a destructuring assignment that spreads the array into distinct variables.
  • Nathan
    Nathan about 2 years
    The default Array.sort() sorts on string value, not numeric value, so Distances[0] won't necessarily be the lowest value.