返回数组中最大值的索引

Ste*_*hen 122 javascript arrays max

我有这个:

var arr = [0, 21, 22, 7];
Run Code Online (Sandbox Code Playgroud)

将最高值的索引返回到另一个变量的最佳方法是什么?

Ry-*_*Ry- 144

这可能是最好的方法,因为它可靠并适用于旧浏览器:

function indexOfMax(arr) {
    if (arr.length === 0) {
        return -1;
    }

    var max = arr[0];
    var maxIndex = 0;

    for (var i = 1; i < arr.length; i++) {
        if (arr[i] > max) {
            maxIndex = i;
            max = arr[i];
        }
    }

    return maxIndex;
}
Run Code Online (Sandbox Code Playgroud)

还有这个单行:

let i = arr.indexOf(Math.max(...arr));
Run Code Online (Sandbox Code Playgroud)

它会根据需要执行两倍的比较,并且会抛出一个RangeError大型数组.我坚持这个功能.

  • 好的,这个函数返回**第一个遇到的索引**作为最大值。假设我有多个具有相同最高值的索引,我如何获取**所有**这些索引? (4认同)
  • @ed1nh0:最简单的方法是进行多次传递。通过 `const max = arr.reduce((m, n) =&gt; Math.max(m, n))` 找到最大值,然后最大值的索引为 `[...arr.keys()].filter (i =&gt; arr[i] === max)`。 (3认同)

tra*_*ium 75

在一行中,可能更快,然后arr.indexOf(Math.max.apply(Math, arr)):

var a = [0, 21, 22, 7];
var indexOfMaxValue = a.reduce((iMax, x, i, arr) => x > arr[iMax] ? i : iMax, 0);

document.write("indexOfMaxValue = " + indexOfMaxValue); // prints "indexOfMaxValue = 2"
Run Code Online (Sandbox Code Playgroud)

哪里:

  • iMax- 到目前为止最好的索引(到目前为止最大元素的索引,在第一次迭代时iMax = 0因为第二个参数reduce()0,reduce()在我们的例子中我们不能省略第二个参数)
  • x - 阵列中当前测试的元素
  • i - 目前测试的指数
  • arr- 我们的数组([0, 21, 22, 7])

关于该reduce()方法(来自David Flanagan的"JavaScript:The Definitive Guide"):

reduce()接受两个参数.第一个是执行缩小操作的功能.此缩减功能的任务是以某种方式将两个值组合或减少为单个值,并返回该减少的值.

与reduce()一起使用的函数与forEach()和map()使用的函数不同.熟悉的值,索引和数组值作为第二,第三和第四个参数传递.第一个论点是到目前为止减少的累积结果.在第一次调用该函数时,第一个参数是您作为reduce()的第二个参数传递的初始值.在后续调用中,它是上一次调用函数返回的值.

当您调用没有初始值的reduce()时,它使用数组的第一个元素作为初始值.这意味着对reduce函数的第一次调用将第一个和第二个数组元素作为其第一个和第二个参数.

  • @traxium虽然您的解释很好,但如果我们使用更多描述性变量,那么对于那些不太熟悉函数式编程的人来说,这个例子可能会更清晰.说:````arr.reduce((bestIndexSoFar,currentTestedValue,currentTestedIndex,array)=> currentTestedValue> array [bestIndexSoFar]?currentTestedIndex:bestIndexSoFar,0);```,可以描述为:从索引开始迭代数组0(第二个参数),如果*currentTestedValue*高于*bestIndexSoFar*中元素的值,则将*currentlyTestedIndex*作为*bestIndexSoFar*返回到下一个迭代. (12认同)
  • @DanielK,"完整"参数名称的答案不适合一个stackoverflow行.会出现一个水平滚动条,在水平滚动时读取片段不是很方便.无论如何,谢谢你的建议.我用另一种方式编辑了答案. (2认同)

Lan*_*ghe 30

这是另一种解决方案,如果您使用扩展运算符使用ES6:

var arr = [0, 21, 22, 7];

const indexOfMaxValue = arr.indexOf(Math.max(...arr));
Run Code Online (Sandbox Code Playgroud)


ran*_*ast 8

max 的另一种解决方案reduce

[1,2,5,0,4].reduce((a,b,i) => a[0] < b ? [b,i] : a, [Number.MIN_VALUE,-1])
//[5,2]
Run Code Online (Sandbox Code Playgroud)

[5e-324, -1]如果数组为空,则返回。如果你只想要索引,把它放在[1]后面。

最小通过(更改为>MAX_VALUE):

[1,2,5,0,4].reduce((a,b,i) => a[0] > b ? [b,i] : a, [Number.MAX_VALUE,-1])
//[0, 3]
Run Code Online (Sandbox Code Playgroud)


Dan*_*Tao 6

除非我弄错了,否则我会说是写自己的功能.

function findIndexOfGreatest(array) {
  var greatest;
  var indexOfGreatest;
  for (var i = 0; i < array.length; i++) {
    if (!greatest || array[i] > greatest) {
      greatest = array[i];
      indexOfGreatest = i;
    }
  }
  return indexOfGreatest;
}
Run Code Online (Sandbox Code Playgroud)


小智 5

如果你正在使用下划线,你可以使用这个漂亮的短单线:

_.indexOf(arr, _.max(arr))
Run Code Online (Sandbox Code Playgroud)

它将首先找到数组中最大项的值,在本例中为22.然后它将返回22在数组中的索引,在本例中为2.


Mat*_*u G 5

为了完成@VFDan 的工作,我对 3 种方法进行了基准测试:接受的一种(自定义循环)、reduce 和 find(max(arr)) 在 10000 个浮点数组上。

在 chromimum 85 linux 上的结果(越高越好):

  • 自定义循环:100%
  • 减少:94.36%
  • indexOf(max): 70%

在 firefox 80 linux 上的结果(越高越好):

  • 自定义循环:100%
  • 减少:96.39%
  • indexOf(max): 31.16%

结论:

如果您需要代码快速运行,请不要使用 indexOf(max)。reduce 没问题,但如果您需要最佳性能,请使用自定义循环。

您可以使用此链接在其他浏览器上运行此基准测试:https : //jsben.ch/wkd4c