在JavaScript中找到数组的最小/最大元素

Find the min/max element of an Array in JavaScript

如何轻松获得JavaScript数组的min或max元素?

伪代码示例:

1
2
3
4
let array = [100, 0, 50]

array.min() //=> 0
array.max() //=> 100


如何扩充内置Array对象以使用Math.max / Math.min代替:

1
2
3
4
5
6
7
Array.prototype.max = function() {
  return Math.max.apply(null, this);
};

Array.prototype.min = function() {
  return Math.min.apply(null, this);
};

这是一个JSFiddle。

增强内置函数可能会导致与其他库发生冲突(有些人看到了),因此您可以更轻松地将Math.xxx()直接添加到数组中:

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

或者,假设您的浏览器支持ECMAScript 6,则可以使用散布运算符,其作用与apply方法类似:

1
2
var min = Math.min( ...arr ),
    max = Math.max( ...arr );


1
var max_of_array = Math.max.apply(Math, array);

有关完整讨论,请参见:
http://aaroncrane.co.uk/2008/11/javascript_max_api/


对于大数组(?10个元素),Math.minMath.max都在Node.js中产生以下错误。

RangeError: Maximum call stack size exceeded

一个更健壮的解决方案是不将每个元素都添加到调用堆栈中,而是传递一个数组:

1
2
3
4
5
6
7
8
9
10
11
function arrayMin(arr) {
  return arr.reduce(function (p, v) {
    return ( p < v ? p : v );
  });
}

function arrayMax(arr) {
  return arr.reduce(function (p, v) {
    return ( p > v ? p : v );
  });
}

如果您担心速度,那么下面的代码将比我的计算机上的Math.max.apply快3倍。参见http://jsperf.com/min-and-max-in-array/2。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
function arrayMin(arr) {
  var len = arr.length, min = Infinity;
  while (len--) {
    if (arr[len] < min) {
      min = arr[len];
    }
  }
  return min;
};

function arrayMax(arr) {
  var len = arr.length, max = -Infinity;
  while (len--) {
    if (arr[len] > max) {
      max = arr[len];
    }
  }
  return max;
};

如果您的数组包含字符串而不是数字,则还需要将它们强制转换为数字。下面的代码可以做到这一点,但是这会使我的计算机上的代码速度降低约10倍。参见http://jsperf.com/min-and-max-in-array/3。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
function arrayMin(arr) {
  var len = arr.length, min = Infinity;
  while (len--) {
    if (Number(arr[len]) < min) {
      min = Number(arr[len]);
    }
  }
  return min;
};

function arrayMax(arr) {
  var len = arr.length, max = -Infinity;
  while (len--) {
    if (Number(arr[len]) > max) {
      max = Number(arr[len]);
    }
  }
  return max;
};


使用传播算子(ES6)

1
Math.max(...array);  // the same with"min" => Math.min(...array);

1
2
3
4
5
const array = [10, 2, 33, 4, 5];

console.log(
  Math.max(...array)
)


TL;博士

1
2
3
4
5
6
7
8
9
10
// For regular arrays:
var max = Math.max(...arrayOfNumbers);

// For arrays with tens of thousands of items:
let max = testArray[0];
for (let i = 1; i < testArrayLength; ++i) {
  if (testArray[i] > max) {
    max = testArray[i];
  }
}

MDN解决方案

Math.max()上的官方MDN文档已涵盖此问题:

The following function uses Function.prototype.apply() to find the maximum element in a numeric array. getMaxOfArray([1, 2, 3]) is equivalent to Math.max(1, 2, 3), but you can use getMaxOfArray() on programmatically constructed arrays of any size.

1
2
3
function getMaxOfArray(numArray) {
    return Math.max.apply(null, numArray);
}

Or with the new spread operator, getting the maximum of an array becomes a lot easier.

1
2
var arr = [1, 2, 3];
var max = Math.max(...arr);

数组的最大大小

根据MDN,apply和散布解决方案的限制为65536,这是由于最大参数个数的限制引起的:

But beware: in using apply this way, you run the risk of exceeding the JavaScript engine's argument length limit. The consequences of applying a function with too many arguments (think more than tens of thousands of arguments) vary across engines (JavaScriptCore has hard-coded argument limit of 65536), because the limit (indeed even the nature of any excessively-large-stack behavior) is unspecified. Some engines will throw an exception. More perniciously, others will arbitrarily limit the number of arguments actually passed to the applied function. To illustrate this latter case: if such an engine had a limit of four arguments (actual limits are of course significantly higher), it would be as if the arguments 5, 6, 2, 3 had been passed to apply in the examples above, rather than the full array.

他们甚至提供了一个混合解决方案,该解决方案与其他解决方案相比并没有真正好的性能。有关更多信息,请参见下面的性能测试。

在2019年,实际限制是调用堆栈的最大大小。对于基于Chromium的现代桌面浏览器,这意味着当使用apply或跨度查找最小值/最大值时,实际上仅数字数组的最大大小为?120000。在此之上,将有一个堆栈溢出,将引发以下错误:

RangeError: Maximum call stack size exceeded

使用下面的脚本(基于此博客文章),通过捕获该错误,您可以计算出特定环境的限制。

警告!运行该脚本需要花费时间,并且取决于您系统的性能,它可能会减慢浏览器/系统或使其崩溃!

1
2
3
4
5
6
7
8
9
10
let testArray = Array.from({length: 10000}, () => Math.floor(Math.random() * 2000000));
for (i = 10000; i < 1000000; ++i) {
  testArray.push(Math.floor(Math.random() * 2000000));
  try {
    Math.max.apply(null, testArray);
  } catch (e) {
    console.log(i);
    break;
  }
}

大型阵列上的性能

基于EscapeNetscape注释中的测试,我创建了一些基准测试,该基准对具有100000个项目的仅随机数数组测试5种不同的方法。

在2019年,结果显示标准循环(BTW没有大小限制)是最快的。 apply和传播紧随其后,然后是MDN的混合解决方案,然后是reduce,是最慢的。

几乎所有测试都给出了相同的结果,唯一不同的是,由于某种原因传播速度最慢。

如果增加阵列以容纳一百万个项目,事情就会开始崩溃,您将使用标准循环作为快速解决方案,而使用reduce作为较慢的解决方案。

JSPerf基准

jsperf.com benchmark results for different solutions to find the min/max item of an array

JSBen基准

jsben.com benchmark results for different solutions to find the min/max item of an array

JSBench.me基准

jsbench.me benchmark results for different solutions to find the min/max item of an array

基准源代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
var testArrayLength = 100000
var testArray = Array.from({length: testArrayLength}, () => Math.floor(Math.random() * 2000000));

// ES6 spread
Math.min(...testArray);
Math.max(...testArray);

// reduce
testArray.reduce(function(a, b) {
  return Math.max(a, b);
});
testArray.reduce(function(a, b) {
  return Math.min(a, b);
});

// apply
Math.min.apply(Math, testArray);
Math.max.apply(Math, testArray);

// standard loop
let max = testArray[0];
for (let i = 1; i < testArrayLength; ++i) {
  if (testArray[i] > max) {
    max = testArray[i];
  }
}

let min = testArray[0];
for (let i = 1; i < testArrayLength; ++i) {
  if (testArray[i] < min) {
    min = testArray[i];
  }
}

// MDN hibrid soltuion
// Source: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply#Using_apply_and_built-in_functions
function minOfArray(arr) {
  var min = Infinity;
  var QUANTUM = 32768;

  for (var i = 0, len = arr.length; i < len; i += QUANTUM) {
    var submin = Math.min.apply(null, arr.slice(i, Math.min(i + QUANTUM, len)));
    min = Math.min(submin, min);
  }

  return min;
}

minOfArray(testArray);

function maxOfArray(arr) {
  var max = -Infinity;
  var QUANTUM = 32768;

  for (var i = 0, len = arr.length; i < len; i += QUANTUM) {
    var submax = Math.max.apply(null, arr.slice(i, Math.max(i + QUANTUM, len)));
    max = Math.max(submax, max);
  }

  return max;
}

maxOfArray(testArray);


如果您像我一样对使用Math.max.apply抱有偏执(根据MDN给定大数组,这可能会导致错误),请尝试以下操作:

1
2
3
4
5
6
7
8
9
10
11
function arrayMax(array) {
  return array.reduce(function(a, b) {
    return Math.max(a, b);
  });
}

function arrayMin(array) {
  return array.reduce(function(a, b) {
    return Math.min(a, b);
  });
}

或者,在ES6中:

1
2
3
4
5
6
7
function arrayMax(array) {
  return array.reduce((a, b) => Math.max(a, b));
}

function arrayMin(array) {
  return array.reduce((a, b) => Math.min(a, b));
}

不幸的是,匿名函数是必需的(而不是使用Math.max.bind(Math),因为reduce不仅将ab传递给其函数,而且传递i和对数组本身的引用,所以我们必须确保我们也不要尝试对这些调用max


当意图是通过参数值列表调用可变参数函数时,通常使用.apply

Math.max([value1[,value2, ...]])函数返回零或多个数字中的最大值。

1
2
3
Math.max(10, 20); // 20
Math.max(-10, -20); // -10
Math.max(-10, 20); // 20

Math.max()方法不允许您传递数组。如果您有一个需要获取最大值的值列表,通常可以使用Function.prototype.apply()调用此函数,例如

1
2
3
Math.max.apply(null, [10, 20]); // 20
Math.max.apply(null, [-10, -20]); // -10
Math.max.apply(null, [-10, 20]); // 20

但是,从ECMAScript 6开始,您可以使用传播运算符:

The spread operator allows an expression to be expanded in places where multiple arguments (for function calls) or multiple elements (for array literals) are expected.

使用散布运算符,可以将上述内容重写为:

1
2
3
Math.max(...[10, 20]); // 20
Math.max(...[-10, -20]); // -10
Math.max(...[-10, 20]); // 20

当使用可变参数运算符调用函数时,您甚至可以添加其他值,例如

1
2
Math.max(...[10, 20], 50); // 50
Math.max(...[-10, -20], 50); // 50

奖金:

Spread运算符使您可以使用数组文字语法在需要使用ESX5,pushsplice等组合的命令式代码的情况下创建新数组。

1
2
let foo = ['b', 'c'];
let bar = ['a', ...foo, 'd', 'e']; // ['a', 'b', 'c', 'd', 'e']


您可以通过扩展Array类型来做到这一点:

1
2
3
4
5
6
Array.max = function( array ){
    return Math.max.apply( Math, array );
};
Array.min = function( array ){
    return Math.min.apply( Math, array );
};

从这里提振(约翰·雷西格)


查找元素Array上的最小值的简单解决方案是使用Array原型函数reduce

1
2
A = [4,3,-9,-2,2,1];
A.reduce((min, val) => val < min ? val : min, A[0]); // returns -9

或使用JavaScript的内置Math.Min()函数(感谢@Tenflex):

1
A.reduce((min,val) => Math.min(min,val), A[0]);

这会将min设置为A[0],然后检查A[1]...A[n]是否严格小于当前的min。如果A[i] < min,则min更新为A[i]。处理完所有数组元素后,将返回min作为结果。


两种方法更短,更容易:

1
2
3
4
5
6
7
8
9
let arr = [2, 6, 1, 0]

// Way 1:
let max = Math.max.apply(null, arr)

//Way 2:
let max = arr.reduce(function(a, b) {
    return Math.max(a, b);
});


另一种方法是:

1
var arrayMax = Function.prototype.apply.bind(Math.max, null);

用法:

1
var max = arrayMax([2, 5, 1]);


其他人已经给出了一些扩展Array.prototype的解决方案。我在此答案中想要的只是澄清它应该是Math.min.apply( Math, array )还是Math.min.apply( null, array )。那么应该使用什么上下文Mathnull

当将null作为上下文传递给apply时,该上下文将默认为全局对象(对于浏览器为window对象)。将Math对象作为上下文传递将是正确的解决方案,但也不会损害通过null传递。这是装饰Math.max函数时null可能引起麻烦的示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// decorate Math.max
(function (oldMax) {
    Math.max = function () {
        this.foo(); // call Math.foo, or at least that's what we want

        return oldMax.apply(this, arguments);
    };
})(Math.max);

Math.foo = function () {
    print("foo");
};

Array.prototype.max = function() {
  return Math.max.apply(null, this); // <-- passing null as the context
};

var max = [1, 2, 3].max();

print(max);

上面将引发异常,因为this.foo将被评估为window.foo,即undefined。如果我们将null替换为Math,一切将按预期进行,并且字符串" foo"将被打印到屏幕上(我使用Mozilla Rhino对此进行了测试)。

您几乎可以假设没有人装饰过Math.max,因此,传递null将毫无问题。


https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/Math/max

1
2
3
4
5
6
function getMaxOfArray(numArray) {
  return Math.max.apply(null, numArray);
}

var arr = [100, 0, 50];
console.log(getMaxOfArray(arr))

这对我有用。


我很惊讶没有人提到减少功能。

1
2
3
4
5
6
7
8
var arr = [1, 10, 5, 11, 2]

var b = arr.reduce(function(previous,current){
                      return previous > current ? previous:current
                   });

b => 11
arr => [1, 10, 5, 11, 2]


这可能适合您的目的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
Array.prototype.min = function(comparer) {

    if (this.length === 0) return null;
    if (this.length === 1) return this[0];

    comparer = (comparer || Math.min);

    var v = this[0];
    for (var i = 1; i < this.length; i++) {
        v = comparer(this[i], v);    
    }

    return v;
}

Array.prototype.max = function(comparer) {

    if (this.length === 0) return null;
    if (this.length === 1) return this[0];

    comparer = (comparer || Math.max);

    var v = this[0];
    for (var i = 1; i < this.length; i++) {
        v = comparer(this[i], v);    
    }

    return v;
}


对于大数组(?10个元素),Math.minMath.max在node.js中引起RangeError(超出最大调用堆栈大小)。

对于大型阵列,一种快速而肮脏的解决方案是:

1
2
3
4
5
Array.prototype.min = function() {
    var r = this[0];
    this.forEach(function(v,i,a){if (v<r) r=v;});
    return r;
};

我遇到了同样的问题,我需要获取数组的最小值和最大值,令我惊讶的是,没有用于数组的内置函数。看了很多书后,我决定自己测试"前三名"解决方案:

  • 离散解决方案:一个FOR循环,根据当前的最大值和/或最小值检查数组的每个元素;
  • APPLY解决方案:使用apply(null,array)将数组发送到Math.max和/或Math.min内部函数;
  • 减少解决方案:使用reduce(function)对数组的每个元素重复进行检查。
  • 测试代码是这样的:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    function GetMaxDISCRETE(A)
    {   var MaxX=A[0];

        for (var X=0;X<A.length;X++)
            if (MaxX<A[X])
                MaxX=A[X];

        return MaxX;
    }

    function GetMaxAPPLY(A)
    {   return Math.max.apply(null,A);
    }

    function GetMaxREDUCE(A)
    {   return A.reduce(function(p,c)
        {   return p>c?p:c;
        });
    }

    数组A填充了100,000个随机整数,在具有Windows Vista的intel Pentium 4 2.99GHz台式机上的Mozilla Firefox 28.0上,每个函数执行了10,000次。时间以秒为单位,由performance.now()函数检索。结果是这些,带有3个小数位数和标准偏差:

  • 离散解:平均值= 0.161s,sd = 0.078
  • 应用解决方案:平均值= 3.571s,标准差= 0.487
  • 减少求解:均值= 0.350s,标准差= 0.044
  • REDUCE解决方案比离散解决方案慢了117%。 APPLY解决方案比离散解决方案更糟,慢了2,118%。此外,正如Peter所言,它不适用于大型数组(大约超过1,000,000个元素)。

    另外,为了完成测试,我测试了以下扩展的离散代码:

    1
    2
    3
    4
    5
    6
    7
    8
    var MaxX=A[0],MinX=A[0];

    for (var X=0;X<A.length;X++)
    {   if (MaxX<A[X])
            MaxX=A[X];
        if (MinX>A[X])
            MinX=A[X];
    }

    计时:平均值= 0.218s,标准偏差= 0.094

    因此,它比简单的离散解决方案要慢35%,但是它一次可以检索最大值和最小值(任何其他解决方案至少要检索两倍)。一旦OP需要两个值,离散解决方案将是最佳选择(即使是两个独立的函数,一个用于计算最大值,另一个用于计算最小值,它们也会胜过第二个最佳方案REDUCE解决方案)。


    您可以在项目中的任何地方使用以下功能:

    1
    2
    3
    4
    5
    6
    7
    function getMin(array){
        return Math.min.apply(Math,array);
    }

    function getMax(array){
        return Math.max.apply(Math,array);
    }

    然后,您可以调用传递数组的函数:

    1
    2
    var myArray = [1,2,3,4,5,6,7];
    var maximo = getMax(myArray); //return the highest number

    以下代码对我有用:

    1
    2
    3
    var valueList = [10,4,17,9,3];
    var maxValue = valueList.reduce(function(a, b) { return Math.max(a, b); });
    var minValue = valueList.reduce(function(a, b) { return Math.min(a, b); });

    反复进行,随时随地进行跟踪。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    var min = null;
    var max = null;
    for (var i = 0, len = arr.length; i < len; ++i)
    {
        var elem = arr[i];
        if (min === null || min > elem) min = elem;
        if (max === null || max < elem) max = elem;
    }
    alert("min =" + min +", max =" + max );

    如果数组中没有元素,则将min / max保留为null。如果数组中有任何元素,将一遍设置最小值和最大值。

    您还可以使用上述方法通过range方法扩展Array,以允许重用并提高可读性。请参阅http://jsfiddle.net/9C9fU/上的小提琴

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    Array.prototype.range = function() {

        var min = null,
            max = null,
            i, len;

        for (i = 0, len = this.length; i < len; ++i)
        {
            var elem = this[i];
            if (min === null || min > elem) min = elem;
            if (max === null || max < elem) max = elem;
        }

        return { min: min, max: max }
    };

    用作

    1
    2
    3
    4
    5
    6
    var arr = [3, 9, 22, -7, 44, 18, 7, 9, 15];

    var range = arr.range();

    console.log(range.min);
    console.log(range.max);


    最小数学和最大数学

    Math.minMath.max都是递归操作,它们很可能会占用较大的数组(大于约10个项目)。

    相反,您可以使用旧的javascript循环,如下所示:

    1
    2
    3
    4
    5
    6
    function getMinMax(arr) {
        return arr.reduce(({min, max}, v) => ({
            min: min < v ? min : v,
            max: max > v ? max : v,
        }), { min: arr[0], max: arr[0] });
    }

    或者(更好的运行时):

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    function getMinMax(arr) {
        let min = arr[0];
        let max = arr[0];
        let i = arr.length;

        while (i--) {
            min = arr[i] < min ? arr[i] : min;
            max = arr[i] > max ? arr[i] : max;
        }
        return { min, max };
    }

    *经过1,000,000项测试:
    仅供参考,第一个函数运行时(在我的计算机上)为15.84ms,而第二个函数运行时仅为4.32ms。


    我以为我会分享我简单易懂的解决方案。

    对于分钟:

    1
    2
    3
    4
    5
    6
    7
    8
    var arr = [3, 4, 12, 1, 0, 5];
    var min = arr[0];
    for (var k = 1; k < arr.length; k++) {
      if (arr[k] < min) {
        min = arr[k];
      }
    }
    console.log("Min is:" + min);

    对于最大:

    1
    2
    3
    4
    5
    6
    7
    8
    var arr = [3, 4, 12, 1, 0, 5];
    var max = arr[0];
    for (var k = 1; k < arr.length; k++) {
      if (arr[k] > max) {
        max = arr[k];
      }
    }
    console.log("Max is:" + max);


    使用Math.max()Math.min()

    1
    2
    Math.max(10, 20);   //  20
    Math.min(-10, -20); // -20

    以下函数使用Function.prototype.apply()在数字数组中查找最大元素。 getMaxOfArray([1, 2, 3])等效于Math.max(1, 2, 3),但是您可以在任何大小的以编程方式构造的数组上使用getMaxOfArray()

    1
    2
    3
    function getMaxOfArray(numArray) {
      return Math.max.apply(null, numArray);
    }

    或使用新的散布运算符,获得数组的最大值变得容易得多。

    1
    2
    3
    var arr = [1, 2, 3];
    var max = Math.max(...arr); // 3
    var min = Math.min(...arr); // 1

    这是一种从对象数组中获取最大值的方法。创建一个副本(带有切片),然后按降序对副本进行排序并获取第一项。

    1
    2
    3
    4
    5
    6
    7
    8
    var myArray = [
        {"ID": 1,"Cost": 200},
        {"ID": 2,"Cost": 1000},
        {"ID": 3,"Cost": 50},
        {"ID": 4,"Cost": 500}
    ]

    maxsort = myArray.slice(0).sort(function(a, b) { return b.ID - a.ID })[0].ID;


    简单的东西,真的。

    1
    2
    3
    4
    5
    var arr = [10,20,30,40];
    arr.max = function() { return  Math.max.apply(Math, this); }; //attach max funct
    arr.min = function() { return  Math.min.apply(Math, this); }; //attach min funct

    alert("min:" + arr.min() +" max:" + arr.max());

    如果您正在使用原型,ChaosPandion的解决方案就可以使用。如果没有,请考虑以下问题:

    1
    2
    3
    4
    5
    6
    7
    Array.max = function( array ){
        return Math.max.apply( Math, array );
    };

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

    如果数组值不是整数,则上面的代码将返回NaN,因此您应该构建一些功能来避免这种情况。否则,它将起作用。


    尝试

    1
    2
    let max= a=> a.reduce((m,x)=> m>x ? m:x);
    let min= a=> a.reduce((m,x)=> m<x ? m:x);

    1
    2
    3
    4
    5
    6
    7
    8
    9
    let max= a=> a.reduce((m,x)=> m>x ? m:x);
    let min= a=> a.reduce((m,x)=> m<x ? m:x);

    // TEST - pixel buffer
    let arr = Array(200*800*4).fill(0);
    arr.forEach((x,i)=> arr[i]=100-i%101);

    console.log('Max', max(arr));
    console.log('Min', min(arr))

    对于Math.min / max(+应用),我们得到错误:

    Maximum call stack size exceeded (Chrome 74.0.3729.131)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    // TEST - pixel buffer
    let arr = Array(200*800*4).fill(0);
    arr.forEach((x,i)=> arr[i]=100-i%101);

    // Exception: Maximum call stack size exceeded

    try {
      let max1= Math.max(...arr);          
    } catch(e) { console.error('Math.max :', e.message) }

    try {
      let max2= Math.max.apply(null, arr);
    } catch(e) { console.error('Math.max.apply :', e.message) }


    // same for min


    1
    2
    3
    4
    let arr = [2,5,3,5,6,7,1];

    let max = Math.max(...arr); // 7
    let min = Math.min(...arr); // 1


    如果使用库sugar.js,则可以按照您的建议编写arr.min()和arr.max()。您还可以从非数值数组中获取最小值和最大值。

    min( map , all = false ) Returns the element in the array with the
    lowest value. map may be a function mapping the value to be checked or
    a string acting as a shortcut. If all is true, will return all min
    values in an array.

    max( map , all = false ) Returns the element in the array with the
    greatest value. map may be a function mapping the value to be checked
    or a string acting as a shortcut. If all is true, will return all max
    values in an array.

    例子:

    1
    2
    3
    4
    5
    6
    [1,2,3].min() == 1
    ['fee','fo','fum'].min('length') =="fo"
    ['fee','fo','fum'].min('length', true) == ["fo"]
    ['fee','fo','fum'].min(function(n) { return n.length; }); =="fo"
    [{a:3,a:2}].min(function(n) { return n['a']; }) == {"a":2}
    ['fee','fo','fum'].max('length', true) == ["fee","fum"]

    Lo-Dash和underscore.js之类的库也提供了类似的强大的min和max函数:

    Lo-Dash的示例:

    1
    2
    3
    4
    5
    6
    _.max([4, 2, 8, 6]) == 8
    var characters = [
      { 'name': 'barney', 'age': 36 },
      { 'name': 'fred',   'age': 40 }
    ];
    _.max(characters, function(chr) { return chr.age; }) == { 'name': 'fred', 'age': 40 }

    如果您使用的是prototype.js框架,则此代码可以正常运行:

    1
    2
    arr.min();
    arr.max();

    此处记录:max的Javascript原型框架


    阅读完所有答案后,我认为编写我遇到的最合理的解决方案(此处未提供)会很好。如果您的值数组可能增长到成千上万,请使用一种混合策略:一次将函数应用于数组的各个块:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    function minOfArray(arr) {
      var min = Infinity;
      var QUANTUM = 32768;

      for (var i = 0, len = arr.length; i < len; i += QUANTUM) {
        var submin = Math.min.apply(null,
                                    arr.slice(i, Math.min(i+QUANTUM, len)));
        min = Math.min(submin, min);
      }

      return min;
    }

    var min = minOfArray([5, 6, 2, 3, 7]);

    资料来源:MDN


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    minHeight = Math.min.apply({},YourArray);
    minKey    = getCertainKey(YourArray,minHeight);
    maxHeight = Math.max.apply({},YourArray);
    maxKey    = getCertainKey(YourArray,minHeight);
    function getCertainKey(array,certainValue){
       for(var key in array){
          if (array[key]==certainValue)
             return key;
       }
    }

    创建一个简单的对象

    1
    2
    3
    4
    5
    6
    7
    8
    9
    var myArray = new Array();

    myArray = [10,12,14,100];

    var getMaxHeight = {
         hight : function( array ){ return Math.max.apply( Math, array );
    }

    getMaxHeight.hight(myArray);


    下面的脚本在ndoejs中为我工作:

    1
    2
     var numbers = [1, 2, 3, 4];
     console.log('Value:: ' + Math.max.apply(null, numbers) ); // 4


    我喜欢Linus的reduce()方法,尤其是对于大型数组。但是,只要您知道同时需要min和max,为什么要在数组上迭代两次?

    1
    2
    3
    4
    5
    Array.prototype.minmax = function () {
      return this.reduce(function (p, v) {
        return [(p[0] < v ? p[0] : v), (p[1] > v ? p[1] : v)];
      }, [this[0], this[0]]);
    }

    当然,如果您喜欢迭代方法,也可以这样做:

    1
    2
    3
    4
    5
    6
    7
    8
    Array.prototype.minmax = function () {
        var mn = this[0], mx = this[0];
        this.forEach(function (v) {
            if (v < mn) mn = v;
            if (v > mx) mx = v;
        });
        return [mn, mx];
    };

    插入用逗号分隔的数字,然后单击要呼叫的事件,即获取最大或最小数字。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
            function maximumNumber() {
           
                var numberValue = document.myForm.number.value.split(",");
                var numberArray = [];
       
                for (var i = 0, len = numberValue.length; i < len; i += 1) {
       
                    numberArray.push(+numberValue[i]);
       
                    var largestNumber = numberArray.reduce(function (x, y) {
                        return (x > y) ? x : y;
                    });
                }
       
                document.getElementById("numberOutput").value = largestNumber;
       
            }
       
            function minimumNumber() {
     
                var numberValue = document.myForm.number.value.split(",");
                var numberArray = [];
       
                for (var i = 0, len = numberValue.length; i < len; i += 1) {
       
                    numberArray.push(+numberValue[i]);
       
                    var smallestNumber = numberArray.reduce(function (x, y) {
                        return (x < y) ? x : y;
                    });
                }
       
                document.getElementById("numberOutput").value = smallestNumber;
       
            }
       
       
                function restrictCharacters(evt) {
       
                    evt = (evt) ? evt : window.event;
                    var charCode = (evt.which) ? evt.which : evt.keyCode;
                    if (((charCode >= '48') && (charCode <= '57')) || (charCode == '44')) {
                        return true;
                    }
                    else {
                        return false;
                    }
                }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
                <form name="myForm">
                <table>
                <tr>
                    <td>Insert Number</td>
                   
                    <td><input type="text" name="number" id="number" onkeypress="return restrictCharacters(event);" /></td>
                   
                    <td><input type="button" value="Maximum" onclick="maximumNumber();" /></td>
                   
                    <td><input type="button" value="Minimum" onclick="minimumNumber();"/></td>
                   
                    <td><input type="text" id="numberOutput" name="numberOutput" /></td>
       
                </tr>
                </table>
                </form>


    线性,几乎纯功能的方法

    1
    var min=[0, 29, 25].map((function(max) {max=-Infinity; return function(e) {return max=Math.max(max, e);}})())[0]

    更多示例:

    找出最小值

    1
    2
    3
    4
    function getMin(arr) {
        return (ar || [0, 29, 25]).
            map((function(max) {max=-Infinity; return function(e) {return max=Math.max(max, e);}})())[0];
    }

    或使用Array.map方法进行变量关闭

    1
    2
    3
    4
    function getMin(arrObjs) {
        return (arrObjs || [{val: 0}, {val: 29}, {val: 25}]).
            map((function(max) {max=-Infinity; return function(e) {return max=(max.val>e.val?max:e);}})())[0];
    }

    找出最大值

    1
    2
    3
    4
    function getMax(arr) {
        return (ar || [0, 29, 25]).
            map((function(v) {v=Infinity; return function(e) {return v=Math.min(v, e);}})())[0];
    }

    用于对象数组

    1
    2
    3
    4
    function getMax(arrObjs) {
        return (arrObjs || [{val: 0}, {val: 29}, {val: 25}]).
            map((function(v) {v=-Infinity; return function(e) {return v=(v.val<e.val?v:e);}})())[0];
    }

    您可能不想向Array原型添加方法,这可能与其他库冲突。

    我已经看到了很多使用forEach的示例,由于其性能较for循环差,因此不建议用于大型阵列。 https://coderwall.com/p/kvzbpa/don-t-use-array-foreach-use-for-instead

    Math.max(Math, [1,2,3]);总是给我NaN吗?

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    function minArray(a) {
      var min=a[0]; for(var i=0,j=a.length;i<j;i++){min=a[i]<min?a[i]:min;}
      return min;
    }

    function maxArray(a) {
      var max=a[0]; for(var i=0,j=a.length;i<j;i++){max=a[i]>max?a[i]:max;}
      return max;
    }

    minArray([1,2,3]); // returns 1

    如果您有对象数组,则下面的minArray()函数示例将接受2个参数,第一个是数组,第二个是要比较的对象键值的键名。在这种情况下,该函数将返回具有最小给定键值的数组的索引。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    function minArray(a, key) {
      var min, i, j, index=0;
      if(!key) {
        min=a[0];
        for(i=0,j=a.length;i<j;i++){min=a[i]<min?a[i]:min;}
        return min;
      }
      min=a[0][key];
      for(i=0,j=a.length;i<j;i++){
        if(a[i][key]<min) {
          min = a[i][key];
          index = i;
        }
      }
        return index;
    }

    var a = [{fee: 9}, {fee: 2}, {fee: 5}];

    minArray(a,"fee"); // returns 1, as 1 is the proper array index for the 2nd array element.


    这是普通的JS方法。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    function getMinArrayVal(seq){
        var minVal = seq[0];
        for(var i = 0; i<seq.length-1; i++){
            if(minVal < seq[i+1]){
            continue;
            } else {
            minVal = seq[i+1];
            }
        }
        return minVal;
    }

    为了防止在" for ... in"循环中列出" max"和" min":

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    Object.defineProperty(Array.prototype,"max", {
        enumerable: false,
        configurable: false,
        writable: false,    
        value: function() {
            return Math.max.apply(null, this);
        }
    });
    Object.defineProperty(Array.prototype,"min", {
        enumerable: false,
        configurable: false,
        writable: false,    
        value: function() {
            return Math.min.apply(null, this);
        }
    });

    用法:

    1
    2
    3
    var x = [10,23,44,21,5];
    x.max(); //44
    x.min(); //5

    如果您有复杂的对象,则可以使用sort ....例如:如果我想要获取包含低于objs的MAX / MIN值的项目。

    1
    2
    3
    4
    5
    6
    7
    var objs= [
    {name:"Apple",value:3},
    {name:"Love",value:32},
    {name:"Cheese",value:1},
    {name:"Pork",value:77},
    {name:"Xmas",value:99}        
    ];

    我会做一个排序:

    1
    objs.sort(function(a, b){return a.value-b.value});

    然后:
    objs[0]是MIN,objs[objs.length-1]是MAX。


    您可以使用Array.sort,但由于默认值为字母,因此您必须编写一个简单的数字排序功能。

    在这里查看示例2。

    然后,您可以抓取arr[0]arr[arr.length-1]以获得最小值和最大值。


    如果您需要性能,那么这是小型阵列的最佳方法:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    var min = 99999;
    var max = 0;
    for(var i = 0; i < v.length; i++)
    {
        if(v[i] < min)
        {
            min = v[i];
        }
        if(v[i] >= max)
        {
            max = v[i];
        }
    }

    这是另一个示例。用lodash计算数组的最大/最小值。

    1
    2
    3
    4
    5
    6
    let array = [100, 0, 50];
    var func = _.over(Math.max, Math.min);
    var [max, min] = func(...array);
    // => [100, 0]
    console.log(max);
    console.log(min);
    1
    <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js">


    我设法通过以下方式解决了我的问题:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
        var strDiv  ="4,8,5,1"
    var arrayDivs   = strDiv.split(",")
    var str ="";

    for (i=0;i<arrayDivs.length;i++)
    {
        if (i<arrayDivs.length-1)
        {
          str = str + eval('arrayDivs['+i+']')+',';
        }
        else if (i==arrayDivs.length-1)
        {
          str = str + eval('arrayDivs['+i+']');
        }
    }

    str = 'Math.max(' + str + ')';
        var numMax = eval(str);

    我希望能有所帮助。

    最好的祝福。