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


777

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

伪代码示例:

let array = [100, 0, 50]

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

93
注:随着ECMAScript中6,你可以使用新的传播经营者:(三个点...带)Math.max()是这样的:Math.max(...[2, 5, 16, 1])。请参阅MDN文档中得到的答案
totymedli

1
考虑将答案标记为已接受。
亚历克斯

这里是最常用方法的速度比较的基准:jsben.ch
#

es6基本上很棒!:)
datdinhquoc

没有ES6 Math.max.apply(null, [2,5,16,1])
Tomer

Answers:


826

如何扩充内置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 );

8
@HankH:通过nullMath{}或任何以apply()call()对结果没有影响。Math.max不也不应在this内部引用。
Roatin Marth,2009年

31
作为C#程序员,我需要强类型问题。
2009年

7
只是分享我在上面的代码中犯的一个jQuery错误,这花了我很长时间进行调试。jQuery数组可以在iPad以外的所有设备上正常工作。我必须将数组转换为真正的本机数组才能正常工作。仅出于某种原因影响了单个设备Math.max.apply(null, $.makeArray(array));
Forrest

11
我已经投票了,因为提议的方法在堆栈帧中消耗了O(n)内存,结果在大型数组上崩溃了。以我为例,大约130000个数字足以使nodejs崩溃。
Alexey Timanovsky

14
不要增加这样的内置原型。这不仅仅是与其他库的冲突;这也与浏览器本身将来提供.maxor .min方法的潜力有关。完全现实的方案:您使用此答案。在2016年,ES7或ES8规范Array.maxArray.min。与该版本不同,它们在字符串上工作。您未来的同事尝试使用现在有据可查的本机.max()方法获取按字母顺序排列的最新字符串,但是神秘地得到NaN。数小时后,她找到了此代码,运行git blame,然后诅咒您的名字。
Mark Amery

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

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


13
Math.max.apply(Math, array)和之间有什么区别Math.max.apply(null, array)?该博客说:“ ...您还必须重复说一遍max属于Math...的内容”,但看来我不必这样做(通过将第一个参数设置为applyas null)。
ziyuang,2015年

9
@ziyuang当您调用like时Math.max(a,b)Math将作为this值传递,因此使用时进行相同的操作可能很有意义apply。但是Math.max不使用该this值,因此您可以传递所需的任何值。
Oriol

199

对于大阵列(〜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;
};

分配minmax最后一个元素,并将迭代次数减少1(while(--len));)
Venugopal 2015年

@Venugopal,那么您需要进行特殊检查以查看数组是否为空并返回+/- Infinity
LinusUnnebäck2015年

2
奇怪...我去了链接的网站...并在Firefox 51.0.0 / Mac OS X 10.12.0中进行了测试,基于reduce的方法比基于loop的方法慢30%...截然不同的结果
Pierpaolo Cira

2
very different results 你这样做5年以后)
АлексейЛещук

1
在2019年reduce解决方案是最慢的。即使您使用具有数百万个元素的数组,也最好使用标准的loop看到我的答案更多。
totymedli

152

使用传播算子(ES6)

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


8
该解决方案已经由多个 其他答案提供。
totymedli

15
Math.max(... [])=-无穷大。哈哈哈😂😂😂
大卫Portabella

@DavidPortabella不知道为什么这很有趣。根据规范,它就是这样工作If no arguments are given, the result is -∞.
Patrick Roberts

3
是的,我的意思是javascript规范太可怕了。显然,没有数字的最小值无法计算。在其他更严格的编程语言(例如Scala)中,请求空数组的最小值将引发异常。
David Portabella

3
Scala适用于需要机器告诉他们做错了事情的人
thedanotto

106

tl; dr

// 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解决方案

官方MDN文档Math.max()已经涵盖了这个问题:

以下函数使用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);

数组的最大大小

根据MDNapply和扩散的解决方案必须从参数的最大数目的限制来了65536的限制:

但要注意:以这种方式使用应用时,存在冒超出JavaScript引擎参数长度限制的风险。应用带有过多参数(考虑成千上万个参数)的函数的结果因引擎而异(JavaScriptCore的硬编码参数限制为65536),因为该限制(甚至包括任何过大堆栈的性质)行为)未指定。一些引擎将引发异常。更有害的是,其他人将任意地限制实际传递给应用函数的参数数量。为了说明后一种情况:如果这样的引擎有四个参数的限制(实际上的限制当然要高得多),则好像在上面的示例中通过了参数5、6、2、3一样,而不是整个数组。

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

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

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

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

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

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针对不同解决方案的基准测试结果,以查找数组的最小/最大项

JSBen基准

jsben.com针对不同解决方案的基准测试结果,以查找数组的最小/最大项

JSBench.me基准

jsbench.me针对不同解决方案的基准测试结果,以查找数组的最小/最大项

基准源代码


如果您使用的是打字稿,则将所示的散布运算符编译为Math.max.apply(Math, arr)具有“最大”兼容性。
Simon_Weaver

1
也来自MDN:“ 如果数组中包含太多元素(...)apply则两者都将传播并失败或返回错误的结果。reduce的解决方案没有此问题。”测试Chrome,FF,Edge和IE11似乎最多可以包含100k个值的数组。(在Win10和最新的浏览器上测试:Chrome 110k,Firefox 300k,Edge 400k,IE11 150k)。
oriadam '18

这是一个非常慢的方法,如果数组有成千上万个元素怎么办?
Slava Fomin II

@SlavaFominII我扩展了答案,因此它涵盖了具有数千个元素的数组。
totymedli

68

如果您像我一样使用偏执狂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它不仅传递a和传递b给函数,还i传递对数组本身的引用,因此我们必须确保我们也不要尝试调用max它们。


您的ES6示例,是否有任何原因不只返回Math.max(...array)
Wojciech Bednarski '16

@WojciechBednarski 此页面似乎暗示使用散布运算符与将数组传递到相同apply,因此具有相同的缺点(最大参数限制)。
丹尼尔·巴克马斯特

谢谢你 只是您可以减少后纠正缺少的支架:function arrayMax(array) { return array.reduce(function(a, b) { return Math.max(a, b); }); // <--------- missing ) }
Arkowsky

1
@DanielDietrich我想做同样的事情Math.min(),不带值调用,返回Infinity,所以这些函数可以reduce(..., Infinity)用来匹配该行为。我更喜欢它抛出一个异常(如当前那样),因为采取空数组的最小值似乎是一个错误。
Daniel Buckmaster

1
到目前为止,减少是最慢的。
АлексейЛещук

40

.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开始,您可以使用传播运算符

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

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

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

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

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

奖金:

价差操作,您可以使用数组文本语法在ES5中,你将需要回落到必要的代码的情况下创建新的阵列,使用的组合pushsplice等等。

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

1
您在奖金中的最后一个示例concat将由大多数程序员编写,因为它使您可以保持单一线条样式。
科迪·艾伦·泰勒

31

两种方法更短,更容易:

let arr = [2, 6, 1, 0]

方式1

let max = Math.max.apply(null, arr)

方式二

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

注意数组是否为空-您将得到负无穷大,可能不是您想要的。如果您愿意,0可以使用[0].concat(arr)或使用扩展语法[0, ...arr](代替“ arr”)
Simon_Weaver

22

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

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

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


20

找到一个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]。处理min完所有数组元素后,将返回结果。

编辑:包括最小值的位置:

A = [4,3,-9,-2,2,1];
A.reduce((min, val) => val < min._min ? {_min: val, _idx: min._curr, _curr: min._curr + 1} : {_min: min._min, _idx: min._idx, _curr: min._curr + 1}, {_min: A[0], _idx: 0, _curr: 0}); // returns { _min: -9, _idx: 2, _curr: 6 }

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

另外一个问题是,如何不仅要min返回值,还要返回它在数组中的位置?
Stevek

@meshfields-我已经更新了答案。
Nicolas Lykke Iversen

15

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

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将毫无问题。


2
点了。但是,为什么有人会装饰Foo.staticMethod和引用this?这不是装饰器设计中的错误吗?(当然,除非他们引用全局范围,并且保持独立于所使用的JavaScript引擎,例如Rhino)。
Roatin Marth,2009年

1
规范明确指出了哪些规范函数应引用“ the this value”(实际上,该短语在规范中出现了125次)。Math.max,未按规范实现this。如果有人重写Math.max它的确使用了this,则表明他们的行为违反规范,因此您应该向他们投掷锋利的物体。您应该围绕这种可能性进行编码,而不是像围绕某人交换的可能性Math.maxMath.minlulz那样进行编码。
马克·阿默里

15

另一种方法是:

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

用法:

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

有人可以解释这是如何工作的吗?这真是涂料。我的理解是正确的:arrayMax是一个函数,我们将某些东西绑定到其原型的属性上吗?这是什么apply.bind,每个原型都有它吗?
山姆


13

这可能适合您的目的。

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

如果没有数字小于0
则应

comparer认为在一些特定的范围被称为?因为它引用的this[index]undefined每次。
Roatin Marth,2009年

固定,我总是忘了功能级别作用域。
2009年

噢,现在,@ Ionut G. Stan会批评您与我一样的“错误上下文”论点,因为您的默认比较器(Math.xxx)将在全球范围内运行...
Roatin Marth

可能是这样,但是新函数签名不需要范围,因为它需要比较两个对象。
2009年


13

替代方法


Math.minMath.max方法都是递归操作正在添加到JS引擎调用堆栈,并且最有可能的崩溃对包含大量项目的数组
(超过〜10⁷项目,取决于用户的浏览器)。

Math.max(... Array(1000000).keys());

未捕获的RangeError:超出最大调用堆栈大小

相反,请使用如下所示的内容:

arr.reduce((max, val) => max > val ? max : val, arr[0])

或具有更好的运行时间:

function maxValue(arr) {
  let max = arr[0];

  for (let val of arr) {
    if (val > max) {
      max = val;
    }
  }
  return max;
}

或同时获得最小和最大:

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,而第二个函数运行时仅为4.32ms。



9

对于大数组(〜10个元素),Math.min以及Math.max在node.js中产生RangeError(超出最大调用堆栈大小)。

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

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

8

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

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

测试代码是这样的:

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个小数位数和标准偏差:

  1. 离散解:平均值= 0.161s,sd = 0.078
  2. 应用解决方案:平均值= 3.571s,标准差= 0.487
  3. 减少求解:均值= 0.350s,标准差= 0.044

REDUCE解决方案比离散解决方案慢了117%。APPLY解决方案比离散解决方案更糟,慢了2,118%。此外,正如Peter所言,它不适用于大型数组(大约超过1,000,000个元素)。

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

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解决方案)。


8

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

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

8

以下代码对我有用:

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

7

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

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/上的小提琴

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

@JordanDillonChapian我同意,但是将其扩展到range将是同时获得IMO最大值和最小值的最佳方法的函数将是微不足道的-正如我对答案所做的更新所做的那样。
tvanfosson 2014年

6

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

对于分钟:

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

对于最大:

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



谢谢。我改变了答案。
Ionut Necula '16

迭代仍然是错误的(访问不存在的属性)。
Bergi '16

出了什么问题,我看不到有什么问题。你能举个例子吗?
Ionut Necula '16

1
现在进行相应修改。希望我能正确理解你。
Ionut Necula '16

6

除了使用数学函数max和min之外,另一个要使用的函数是sort()的内置函数:

const nums = [12, 67, 58, 30].sort((x, y) => 
x -  y)
let max = nums[0]
let min = nums[nums.length -1]

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

5

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

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; 

5

使用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

4

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

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

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

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


jeerose,为什么当Roatin Marth只有(null,this)时,您为什么要(Math,this)作为副食品?
HankH,2009年

@HankH:在评论我自己的答案时,请参阅我对您评论的回复。
Roatin Marth,2009年

1
我不明白“如果使用原型,ChaosPandion的解决方案有效”的含义。除了将Math对象用作上下文之外,您的解决方案有何不同?
Ionuț G. Stan,

抱歉,我的意思是,如果您扩展原型,则可以使用。道歉。
jay

那么,使用jeerose还是ChaosPandion哪个更好?
HankH,2009年

3

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

min(map,all = false)返回数组中具有最低值的元素。map可以是映射要检查的值的函数,也可以是用作快捷方式的字符串。如果all为true,则将返回数组中的所有min值。

max(map,all = false)返回数组中具有最大值的元素。map可以是映射要检查的值的函数,也可以是充当快捷方式的字符串。如果all为true,则将返回数组中的所有最大值。

例子:

[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-Dashunderscore.js之类的库也提供了类似的强大的min和max函数:

Lo-Dash的示例:

_.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 }

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

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

2
该解决方案已经由其他多个回答者提供。您的答案增加了什么?
尼克,

3

尝试

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

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

超过最大通话堆栈大小(Chrome 74.0.3729.131)

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.