ChatGPT解决这个技术问题 Extra ChatGPT

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

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

示例伪代码:

let array = [100, 0, 50]

array.min() //=> 0
array.max() //=> 100
注意: 对于 ECMAScript 6,您可以使用新的 spread operator(三个点:...)和 Math.max(),如下所示:Math.max(...[2, 5, 16, 1])。请参阅由 MDN documentation 制成的 my answer
这里是最常用方法的速度比较基准:jsben.ch/#/1QuTg
在 ES6 中,同时获取最大值和最小值可以是 done with only one reduce call
@AronFiechter 你真的读过我的答案吗?我通过代码示例和基准非常详细地解释了所有选项。只有当您的数组大小大于 100000 时,调用堆栈大小才会成为问题。虽然必须考虑调用堆栈,但在大多数情况下,这不是问题,更简洁的代码胜过缺点。
此调用堆栈可能是一个问题。有一个 HackerRank 问题需要找到最小值和最大值,并且测试在 10 秒的限制下运行。 HackerRank 为第 9 到第 14 次测试传入的数组长度大于 100,000;如果使用以下答案中的 reduce 解决方案,则会失败。 for循环将通过一些

R
RobG

如何扩充内置 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); };让 p = [35,2,65,7,8,9,12,121,33,99]; console.log(`最大值为:${p.max()}` + `\n最小值为:${p.min()}`);

这是一个JSFiddle

增加内置函数可能会导致与其他库发生冲突(有些人看到),因此您可能更愿意直接将 Math.xxx() apply 写入您的数组:

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

或者,假设您的浏览器支持 ECMAScript 6,您可以使用 spread syntax,其功能类似于 apply 方法:

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

@HankH:也许吧。 Math.max 类似于“静态”方法,因此其中没有有用的 this 实例(我希望如此)。所以假设这是真的,调用它会在全局范围内运行它(即 window),这相当于将 null 作为第一个参数传递给 apply/call
@HankH:将 nullMath{} 或其他任何东西传递给 apply()call() 对结果没有影响。 Math.max 不会也不应该在内部引用 this
只是分享我在上面的代码中犯的一个 jQuery 错误,这花了我很长时间来调试。 jquery 数组可以在除 iPad 之外的所有设备上正常工作。我必须将数组转换为真正的本机数组才能工作。由于某种原因仅影响了单个设备Math.max.apply(null, $.makeArray(array));
我投了反对票,因为提议的方法在堆栈帧中消耗 O(n) 内存,因此在大型数组上崩溃。在我的例子中,只有大约 130000 个数字就足以让 nodejs 崩溃。
不要像这样增加内置原型。这不仅仅是与其他库的冲突;这也与浏览器本身在未来提供 .max.min 方法的可能性有关。完全真实的场景:你使用这个答案。 2016 年,ES7 或 ES8 规范 Array.maxArray.min。与此版本不同,它们适用于字符串。您未来的同事尝试使用现在有据可查的原生 .max() 方法在数组中获取按字母顺序排列的最新字符串,但神秘地得到了 NaN。几小时后,她找到了这段代码,运行了 git blame 并诅咒了你的名字。
G
GSerg
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 值,因此您可以传递任何您想要的值。
E
EscapeNetscape

对于大数组(~10⁷ 元素),Math.minMath.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 倍。请参阅https://jsben.ch/JPOyL

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 倍。请参阅https://jsben.ch/uPipD

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 那么您需要进行特殊检查以查看数组是否为空并返回 +/- Infinity
奇怪...我去了链接的网站...并在 Firefox 51.0.0 / Mac OS X 10.12.0 中进行测试,基于 reduce 的方法比基于循环的方法慢 30% ......结果非常不同
jsperf.com/array-min-max-random/1 从 60 个元素开始,数学方法与 while 循环打破相等,如果数组大小大于 60,则数学方法获胜。数组越大 - 数学方法越多。 (100 elems Math.min/max 快 10%,1000 elems +25%)
在 2019 年reduce 解决方案最慢。即使您使用包含数百万个元素的数组,最好使用标准 for 循环See my answer for more.
G
Gass

使用扩展运算符 (ES6)

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

常量数组 = [10, 2, 33, 4, 5]; console.log(Math.max(...array))


此解决方案已由 multiple other 个答案提供。
Math.max(...[]) = -无穷大。哈哈哈😂😂😂
@DavidPortabella 不知道为什么这很有趣。这就是它的工作原理according to the specificationIf no arguments are given, the result is -∞.
是的,我的意思是 javascript 规范很糟糕。显然,无法计算任何数字的最小值。在其他更严肃的编程语言中,例如 Scala,询问空数组的最小值会引发异常。
Scala 适用于需要机器来告诉他们他们做错了的人
t
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];
  }
}

MDN 解决方案

official MDN docs on Math.max() 已涵盖此问题:

以下函数使用 Function.prototype.apply() 查找数值数组中的最大元素。 getMaxOfArray([1, 2, 3]) 等价于 Math.max(1, 2, 3),但您可以在以编程方式构造的任意大小的数组上使用 getMaxOfArray()。函数 getMaxOfArray(numArray) { return Math.max.apply(null, numArray);或者使用新的扩展运算符,获取数组的最大值变得容易得多。 var arr = [1, 2, 3]; var max = Math.max(...arr);

数组的最大大小

According to MDN apply 和传播解决方案具有 65536 的限制,这是来自最大参数数量的限制:

但请注意:以这种方式使用 apply 时,可能会超出 JavaScript 引擎的参数长度限制。应用带有太多参数的函数(考虑超过数万个参数)的后果因引擎而异(JavaScriptCore 的硬编码参数限制为 65536),因为限制(实际上甚至是任何过大堆栈的性质行为)未指定。有些引擎会抛出异常。更有害的是,其他人会任意限制实际传递给应用函数的参数数量。为了说明后一种情况:如果这样的引擎有四个参数的限制(实际限制当然要高得多),就好像参数 5、6、2、3 已被传递以应用于上面的示例,而不是整个数组。

他们甚至提供了一种混合解决方案,与其他解决方案相比,它的性能并不好。有关更多信息,请参阅下面的性能测试。

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

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

使用下面的脚本(基于 this blog post),通过捕获该错误,您可以计算特定环境的限制。

警告!运行此脚本需要时间,并且根据您的系统性能,它可能会减慢或崩溃您的浏览器/系统!

让 testArray = Array.from({length: 10000}, () => Math.floor(Math.random() * 2000000)); for (i = 10000; i < 1000000; ++i) { testArray.push(Math.floor(Math.random() * 2000000));尝试 { Math.max.apply(null, testArray); } 捕捉 (e) { console.log(i);休息; } }

大型阵列上的性能

根据 EscapeNetscape 评论中的测试,我创建了一些基准测试,在具有 100000 个项目的仅随机数数组上测试 5 种不同的方法。

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

几乎所有的测试都给出了相同的结果,除了一个传播速度最慢的测试。

如果您将数组提高到拥有 100 万个项目,事情就会开始中断,您将使用标准循环作为快速解决方案,而 reduce 作为较慢的解决方案。

JSPerf 基准测试

https://i.stack.imgur.com/5NHlm.png

JSBen 基准测试

https://i.stack.imgur.com/DcC0N.png

JSBench.me 基准测试

https://i.stack.imgur.com/WTOs3.png

基准测试源代码

var testArrayLength = 100000 var testArray = Array.from({length: testArrayLength}, () => Math.floor(Math.random() * 2000000)); // ES6 传播 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); }); // 应用 Math.min.apply(Math, testArray); Math.max.apply(Math, testArray); // 标准循环 let max = testArray[0]; for (let i = 1; i < testArrayLength; ++i) { if (testArray[i] > max) { max = testArray[i]; } } 让 min = testArray[0]; for (let i = 1; i < testArrayLength; ++i) { if (testArray[i] < min) { min = testArray[i]; } } // MDN 混合解决方案 // 来源: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 = 无穷大;变量量子 = 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); } 返回分钟; } minOfArray(testArray);函数 maxOfArray(arr) { var max = -Infinity;变量量子 = 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); } 返回最大值; } maxOfArray(testArray);


如果您使用打字稿,则显示的展开运算符将编译为 Math.max.apply(Math, arr) 以实现“最大”兼容性。
同样来自 MDN:“如果数组元素过多,传播 (...)apply 都将失败或返回错误结果 [...]reduce 解决方案没有这个问题”测试 Chrome、FF、Edge 和IE11 似乎可以容纳最多 100k 个值的数组。 (在 Win10 和最新浏览器上测试:Chrome 110k、Firefox 300k、Edge 400k、IE11 150k)。
这是一个非常慢的方法,如果数组有数千个元素怎么办?
@SlavaFominII 我扩展了答案,因此它涵盖了具有数千个元素的数组。
D
Daniel Buckmaster

如果您像我一样偏执于使用 Math.max.apply(在给定大型数组 according to 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


您的 ES6 示例,有什么理由不直接返回 Math.max(...array) 吗?
@WojciechBednarski this page 似乎暗示使用扩展运算符与将数组传递给 apply 相同,因此具有相同的缺点(最大参数限制)。
谢谢你。只是你可以在减少后纠正丢失的括号:function arrayMax(array) { return array.reduce(function(a, b) { return Math.max(a, b); }); // <--------- missing ) }
@DanielDietrich 我猜想做同样的事情,调用不带值的 Math.min(),返回 Infinity,因此这些函数可以使用 reduce(..., Infinity) 来匹配该行为。我更喜欢它抛出一个异常(就像它目前所做的那样),因为取一个空数组的最小值似乎可能是一个错误。
到目前为止,reduce 是最慢的。
L
Lior Elrom

替代方法

Math.minMath.max 是从项目集合中获取最小和最大项目的好方法,但重要的是要注意它可能附带的一些空洞。

将它们与包含大量项目(超过 ~107 个项目,取决于用户的浏览器)的数组很可能会崩溃并给出以下错误消息:

const arr = Array.from(Array(1000000).keys());
Math.min(arr);
Math.max(arr);

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

更新
最新的浏览器可能会返回 NaN。这可能是处理错误的更好方法,但它还不能解决问题。

相反,考虑使用类似这样的东西:

function maxValue(arr) {
  return arr.reduce((max, val) => max > val ? max : val)
}

或者具有更好的运行时间:

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.84 毫秒,而第二个函数只有 4.32 毫秒。


只需传播阵列。 Math.min(...arr)
@RicardoNolde 不幸的是,传播数组并没有改变 Math.min/max 函数的工作方式(在 Chrome v91 上测试)。如果这对您有用,请分享您使用的浏览器/版本。
对不起,我应该更清楚。发生 NaN 问题是因为您传递的是一个直数组。在我测试过的浏览器中,它总是返回 NaN;这可以通过扩展数组来解决。您提出的另一个问题——最大调用堆栈大小——仍然适用,无论分布如何。
H
Hafizur Rahman

两种方法更短更容易:

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

方式一:

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”)
有没有办法在方式 1 中排除空值?
@hafizur-rahman 方式 #1 无法处理大量数字! (如#2可以)。尝试使用超过 ~10⁷ 项的任何数组 - Array.from(Array(1000000).keys())
G
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 operator

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

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

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']

大多数程序员将使用 concat 编写奖金中的最后一个示例,因为它使您可以保持单线样式。
b
brettkelly

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

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

here 提升(由 John Resig)


N
Nicolas Lykke Iversen

找到 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]);

这会将 min 设置为 A[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 }

A.reduce((min,val) => Math.min(min,val),A[0]);更短
作为一个额外的问题,如何不仅返回 min 值,而且返回它在数组中的位置?
U
Unmitigated

对于简洁的现代解决方案,可以对数组执行 reduce 操作,跟踪当前的最小值和最大值,因此数组只迭代一次(这是最佳的)。为了简洁起见,这里使用 Destructuring assignment

让数组 = [100, 0, 50];让 [min, max] = array.reduce(([prevMin,prevMax], curr)=> [Math.min(prevMin, curr), Math.max(prevMax, curr)], [Infinity, -Infinity]); console.log("Min:", min); console.log("Max:", max);

为了只找到最小值或最大值,我们可以使用几乎相同的方式执行 reduce 操作,但我们只需要跟踪之前的最优值。此方法比使用 apply 更好,因为当数组对于堆栈而言太大时,它不会导致错误。

常量 arr = [-1, 9, 3, -6, 35]; //只求最小值 const min = arr.reduce((a,b)=>Math.min(a,b), Infinity); console.log("Min:", min);//-6 //只求最大值 const max = arr.reduce((a,b)=>Math.max(a,b), -Infinity); console.log("Max:", max);//35


I
Ionuț G. Stan

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

null 作为上下文传递给 apply 时,上下文将默认为全局对象(浏览器中的 window 对象)。将 Math 对象作为上下文传递是正确的解决方案,但传递 null 也无妨。以下是装饰 Math.max 函数时 null 可能导致问题的示例:

// 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 将毫无问题地工作。


取点。但是,为什么有人会装饰 Foo.staticMethod 并引用 this?这不是装饰器设计的错误吗? (当然,除非他们想要引用全局范围,并且想要保持独立于所使用的 JavaScript 引擎,例如 Rhino)。
The spec 明确指出哪些指定函数应引用“this 值”(实际上,该短语在规范中出现了 125 次)。 Math.max,按规范实现,不使用 this。如果有人重写 Math.max 以使其确实使用 this,那么他们的行为违反了规范,您应该向他们扔尖锐的物体。您不应该围绕这种可能性进行编码,就像围绕有人将 Math.maxMath.min 交换为 lulz 的可能性进行编码一样。
g
gion_13

另一种方法:

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

用法:

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

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

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

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]

请注意:从 IE9 开始支持 reduce(),请参阅 developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
我似乎无法在当前版本的 Chromium 中使用它。
R
Ruslan López

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

函数 getMaxOfArray(numArray) { return Math.max.apply(null, numArray); } var arr = [100, 0, 50]; console.log(getMaxOfArray(arr))

这对我有用。


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

你应该用'this [0]'初始化你的v,以防没有数字小于0
comparer 是否应该在某个特定范围内调用?因为它每次都引用 this[index],即 undefined
已修复,我总是忘记功能级别范围。
哦,现在,@Ionut G. Stan 会批评你的“错误上下文”论点,因为你的默认比较器(Math.xxx)将在全局范围内运行......
这可能是真的,但新函数签名不需要范围,因为它需要需要比较的 2 个对象。
T
Trilok Singh

让数组 = [267, 306, 108] 让最长 = Math.max(...array);


totymedli’s answerC.K’s answerAbdennour TOUMI’s answershilovk’s answer 中已经提到了这种确切的方法,不包括所有已删除的答案。您的(未格式化的)答案没有添加任何内容。
I
Ionut

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

对于分钟:

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

对于最大值:

var arr = [3, 4, 12, 1, 0, 5];变量最大值 = arr[0]; for (var k = 1; k < arr.length; k++) { if (arr[k] > max) { max = arr[k]; } } console.log("最大值为:" + max);


谢谢。我改变了答案。
迭代仍然是错误的(访问不存在的属性)。
有什么问题,我看不出有什么问题。你能举个例子吗?
现作相应修改。希望我理解正确。
P
Peter

对于大数组(~10⁷ 元素),Math.minMath.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;
};

b
black.swordsman

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

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

嗯,sort() 不会花费 O(n*log(n)) 时间,而仅仅迭代数组会花费线性时间?
C
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;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 个小数位数和标准偏差:

离散解:mean=0.161s,sd=0.078 APPLY 解:mean=3.571s,sd=0.487 REDUCE 解:mean=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;X<A.length;X++)
{   if (MaxX<A[X])
        MaxX=A[X];
    if (MinX>A[X])
        MinX=A[X];
}

计时:mean=0.218s,sd=0.094

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


f
falsarella

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

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

G
Gogol BH Network

以下代码适用于我:

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

l
laktak

对于包含对象而不是数字的数组:

arr = [
  { name: 'a', value: 5 },
  { name: 'b', value: 3 },
  { name: 'c', value: 4 }
]

您可以使用 reduce 获取具有最小值 (min) 的元素

arr.reduce((a, b) => a.value < b.value ? a : b)
// { name: 'b', value: 3 }

或最大值(max)

arr.reduce((a, b) => a.value > b.value ? a : b)
// { name: 'a', value: 5 }

S
Shashwat Gupta

让 arr=[20,8,29,76,7,21,9] Math.max.apply( Math, arr ); // 76


t
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 为空。如果数组有任何元素,将一次性设置最小值和最大值。

您还可以使用上述方法使用 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 - 正如我对我的更新所做的那样回答。
A
Adam Beleko
array.sort((a, b) => b - a)[0];

为您提供数字数组中的最大值。

array.sort((a, b) => a - b)[0];

为您提供数字数组中的最小值。

让数组 = [0,20,45,85,41,5,7,85,90,111];让最大值 = array.sort((a, b) => b - a)[0];让最小值 = array.sort((a, b) => a - b)[0]; console.log(最小,最大)


f
falsarella

简单的东西,真的。

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

f
falsarella

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

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;