当前位置:  开发笔记 > 编程语言 > 正文

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

如何解决《在JavaScript中查找数组的最小/最大元素》经验,为你挑选了25个好方法。

如何轻松获取JavaScript数组的最小或最大元素?

示例Psuedocode:

let array = [100, 0, 50]

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

Roatin Marth.. 783

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

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

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

这是一个JSFiddle.

增强的内置插件可能会导致与其他库(一些人认为)的碰撞,所以你可能会更舒服只是apply"荷兰国际集团Math.xxx()直接向您的数组:

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

或者,假设您的浏览器支持ECMAScript 6,您可以使用与该方法类似的扩展运算符apply:

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

作为一名C#程序员,我需要强类型的问题. (28认同)

不要像这样增加内置原型.这不仅仅是与其他图书馆的冲突; 它也是关于浏览器本身在将来提供`.max`或`.min`方法的潜力.非常逼真的场景:*你使用这个答案.2016年,ES7或ES8规范`Array.max`和`Array.min`.与此版本不同,它们适用于字符串.你未来的同事试图用现在记录良好的原生`.max()`方法将数字字母最新的字符串放在一个数组中,但神秘地得到`NaN`.几个小时后,她发现这个代码,运行一个'git blame`,并诅咒你的名字.* (12认同)

我投票,因为提议的方法在堆栈帧中消耗O(n)内存,因此在大型数组上崩溃.在我的情况下,只有大约130000个数字足以崩溃nodejs. (10认同)

@HankH:传递`null`或`Math`或`{}`或者什么来对'apply()`或`call()`与结果无关.`Math.max`不会也不应该在内部引用`this`. (8认同)

只是分享一个jQuery错误,我正在使用上面的代码,这花了我很长时间来调试.除了iPad之外,jquery数组在所有内容上都能正常工作.我必须将数组转换为真正的本机数组才能工作.仅因某种原因影响单个设备`Math.max.apply(null,$ .makeArray(array));` (7认同)

@HankH:也许吧.`Math.max`类似于"静态"方法,所以内部没有有用的`this`实例(我希望).所以假设这是真的,调用它将在全局范围内运行它(即`window`),这相当于将`null`作为第一个参数传递给`apply` /`call`. (4认同)

不应该是"返回Math.max.apply(数学,这个);" 并且不返回Math.max.apply(null,this); (2认同)

@ChaosPandion:你是对的.这不适用于任何其他类型. (2认同)

...或者只是包装代码`if(!Array.max){...}`,这样如果浏览器确实添加了这些方法,它们就不会被替换. (2认同)


newspire.. 346

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

如需全面讨论,请访问:http: //aaroncrane.co.uk/2008/11/javascript_max_api/



1> Roatin Marth..:

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

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

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

这是一个JSFiddle.

增强的内置插件可能会导致与其他库(一些人认为)的碰撞,所以你可能会更舒服只是apply"荷兰国际集团Math.xxx()直接向您的数组:

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

或者,假设您的浏览器支持ECMAScript 6,您可以使用与该方法类似的扩展运算符apply:

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


作为一名C#程序员,我需要强类型的问题.
不要像这样增加内置原型.这不仅仅是与其他图书馆的冲突; 它也是关于浏览器本身在将来提供`.max`或`.min`方法的潜力.非常逼真的场景:*你使用这个答案.2016年,ES7或ES8规范`Array.max`和`Array.min`.与此版本不同,它们适用于字符串.你未来的同事试图用现在记录良好的原生`.max()`方法将数字字母最新的字符串放在一个数组中,但神秘地得到`NaN`.几个小时后,她发现这个代码,运行一个'git blame`,并诅咒你的名字.*
我投票,因为提议的方法在堆栈帧中消耗O(n)内存,因此在大型数组上崩溃.在我的情况下,只有大约130000个数字足以崩溃nodejs.
@HankH:传递`null`或`Math`或`{}`或者什么来对'apply()`或`call()`与结果无关.`Math.max`不会也不应该在内部引用`this`.
只是分享一个jQuery错误,我正在使用上面的代码,这花了我很长时间来调试.除了iPad之外,jquery数组在所有内容上都能正常工作.我必须将数组转换为真正的本机数组才能工作.仅因某种原因影响单个设备`Math.max.apply(null,$ .makeArray(array));`
@HankH:也许吧.`Math.max`类似于"静态"方法,所以内部没有有用的`this`实例(我希望).所以假设这是真的,调用它将在全局范围内运行它(即`window`),这相当于将`null`作为第一个参数传递给`apply` /`call`.
不应该是"返回Math.max.apply(数学,这个);" 并且不返回Math.max.apply(null,this);
@ChaosPandion:你是对的.这不适用于任何其他类型.
...或者只是包装代码`if(!Array.max){...}`,这样如果浏览器确实添加了这些方法,它们就不会被替换.

2> newspire..:
var max_of_array = Math.max.apply(Math, array);

如需全面讨论,请访问:http: //aaroncrane.co.uk/2008/11/javascript_max_api/


`Math.max.apply(Math,array)`和`Math.max.apply(null,array)`有什么区别?博客说"你还必须多余地再说'max`属于'Math` ......",但似乎我不必这样做(通过设置`apply`的第一个参数为`null`).
@ziyuang当你把它称为`Math.max(a,b)`时,`Math`作为`this`值传递,所以用`apply`调用时也可以这样做.但是`Math.max`不使用`this`值,所以你可以传递你想要的任何值.

3> Linus Unnebä..:

对于大阵列(〜10⁷元素),Math.min并且Math.max二者在产生Node.js的下面的错误

RangeError:超出最大调用堆栈大小

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

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.

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.

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;
};


奇怪...我去了链接的网站...并在Firefox 51.0.0 / Mac OS X 10.12.0中进行了测试,基于reduce的方法比基于loop的方法慢30%...截然不同的结果
“非常不同的结果”,您在5年后做了此操作)

4> Abdennour TO..:

使用扩展运算符(ES6)

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

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

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


5> totymedli..:

TL;博士

// 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];
  }
}

官方Math.max()MDN文档

以下函数使用Function.prototype.apply()来查找数值数组中的最大元素.getMaxOfArray([1, 2, 3])相当于Math.max(1, 2, 3),但您可以使用getMaxOfArray()任何大小的编程构造数组.

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

或者使用新的扩展运算符,获得数组的最大值变得更加容易.

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



6> Daniel Buckm..:

如果你像我一样偏执狂使用Math.max.apply(根据MDN给出大数组可能会导致错误),试试这个:

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中:

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,以及那些.



7> Gajus..:

.apply 当意图使用参数值列表调用可变参数函数时经常使用,例如

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

Math.max(10, 20); // 20
Math.max(-10, -20); // -10
Math.max(-10, 20); // 20

Math.max()方法不允许您传入数组.如果你有一个你需要获得最大值的列表,你通常会使用Function.prototype.apply()来调用这个函数,例如

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

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

spread运算符允许在需要多个参数(用于函数调用)或多个元素(用于数组文字)的位置扩展表达式.

使用扩展运算符,可以重写上述内容:

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

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

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

奖金:

价差操作,您可以使用数组文本语法在ES5,你将需要退回到命令式代码的情况下创建新的阵列,使用的组合push,splice等等.

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



8> inkedmn..:

您可以通过扩展Array类型来实现:

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

从这里开始(由John Resig提供)



9> 小智..:

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

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

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

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

设置minA[0],然后检查A[1]...A[n]它是否严格小于当前min.如果A[i] < min随后min更新为A[i]通过返回该值.


A.reduce((min,val)=> Math.min(min,val),A [0]); 甚至更短

10> Hafizur Rahm..:

两种方式更简单:

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);
});



11> Ionuț G. Sta..:

其他人已经提出了一些可以增强的解决方案Array.prototype.我在这个答案中想要的是澄清它是否应该是Math.min.apply( Math, array )Math.min.apply( null, array ).那么应该使用什么背景,Math或者null

null作为上下文传递时apply,上下文将默认为全局对象(在window浏览器的情况下为对象).将Math对象作为上下文传递将是正确的解决方案,但它也不会伤害传递null.这是一个null在装饰Math.max功能时可能会造成麻烦的例子:

// 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.如果我们替换nullMath,事情将按预期工作,字符串"foo"将打印到屏幕上(我使用Mozilla Rhino测试过).

你几乎可以假设没有人装饰过Math.max,传递null将毫无问题地工作.


采取的点.然而,为什么有人会装饰`Foo.staticMethod`并引用`this`?在装饰设计中这不是一个错误吗?(当然,除非他们*希望*引用全局范围,并且*希望*保持独立于所使用的JavaScript引擎,例如Rhino).

12> sbr..:

还有一种方法:

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

用法:

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



13> Fuad Ibrahim..:

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

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

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


14> 小智..:

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

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]



15> ChaosPandion..:

这可能适合您的目的.

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;
}



16> Peter..:

对于大数组(~ 10⁷ 元素),Math.minMath.max在node.js中产生RangeError(超出最大调用堆栈大小).

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

Array.prototype.min = function() {
    var r = this[0];
    this.forEach(function(v,i,a){if (v



17> Cyberknight..:

我遇到了同样的问题,我需要获取数组的最小值和最大值,令我惊讶的是,没有内置的数组函数.经过大量阅读后,我决定自己测试"前3名"解决方案:

    离散解决方案:一个FOR循环,用于检查数组中每个元素的当前最大值和/或最小值;

    APPLY解决方案:使用apply(null,array)将数组发送到Math.max和/或Math.min内部函数;

    REDUCE解决方案:使用reduce(function)对数组的每个元素进行检查.

测试代码是这样的:

function GetMaxDISCRETE(A)
{   var MaxX=A[0];

    for (var X=0;Xc?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

    APPLY solution:mean = 3.571s,sd = 0.487

    REDUCE解决方案:平均值= 0.350s,sd = 0.044

REDUCE解决方案比分立解决方案慢117%.APPLY解决方案更糟糕,比分立解决方案慢2,118%.此外,正如Peter所说,它不适用于大型阵列(大约超过1,000,000个元素).

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

var MaxX=A[0],MinX=A[0];

for (var X=0;XA[X])
        MinX=A[X];
}

时间:平均值= 0.218s,sd = 0.094

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



18> 小智..:

您可以在项目的任何位置使用以下功能:

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

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

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

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



19> 小智..:

以下代码适用于我:

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); });



20> Lior Elrom..:
Math.min和Math.max

Math.minMath.max都是递归运算其中最有可能crach的大阵列(大于〜10⁷项目).

相反,你可以像这样使用旧的javascript循环:

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] });
}

或者(更好的运行时间):

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 vs第二个功能,只有4.32ms.



21> tvanfosson..:

迭代,随时跟踪.

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.如果数组有任何元素,将在一次传递中设置min和max.

您还可以range使用上述方法扩展Array 以允许重用并提高可读性.在http://jsfiddle.net/9C9fU/看到一个工作小提琴

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 }
};

用作

var arr = [3, 9, 22, -7, 44, 18, 7, 9, 15];

var range = arr.range();

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



22> Ionut Necula..:

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

对于分钟:

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);


23> 小智..:

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

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; 



24> Brian..:

简单的东西,真的.

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());



25> shilovk..:

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

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

以下函数用于Function.prototype.apply()查找数值数组中的最大元素.getMaxOfArray([1, 2, 3])相当于Math.max(1, 2, 3),但您可以使用getMaxOfArray()任何大小的编程构造数组.

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

或者使用新的扩展运算符,获得数组的最大值变得更加容易.

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

推荐阅读
保佑欣疼你的芯疼
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有