I have this:
var arr = [0, 21, 22, 7];
What's the best way to return the index of the highest value into another variable?
This question is related to
javascript
arrays
max
A stable version of this function looks like this:
// not defined for empty array
function max_index(elements) {
var i = 1;
var mi = 0;
while (i < elements.length) {
if (!(elements[i] < elements[mi]))
mi = i;
i += 1;
}
return mi;
}
Here is another solution, If you are using ES6 using spread operator:
var arr = [0, 21, 22, 7];
const indexOfMaxValue = arr.indexOf(Math.max(...arr));
function findIndicesOf(haystack, needle)
{
var indices = [];
var j = 0;
for (var i = 0; i < haystack.length; ++i) {
if (haystack[i] == needle)
indices[j++] = i;
}
return indices;
}
pass array
to haystack
and Math.max(...array)
to needle
. This will give all max elements of the array, and it is more extensible (for example, you also need to find min values)
If you are utilizing underscore, you can use this nice short one-liner:
_.indexOf(arr, _.max(arr))
It will first find the value of the largest item in the array, in this case 22. Then it will return the index of where 22 is within the array, in this case 2.
EDIT: Years ago I gave an answer to this that was gross, too specific, and too complicated. So I'm editing it. I favor the functional answers above for their neat factor but not their readability; but if I were more familiar with javascript then I might like them for that, too.
Pseudo code:
Track index that contains largest value. Assume index 0 is largest initially. Compare against current index. Update index with largest value if necessary.
Code:
var mountains = [3, 1, 5, 9, 4];
function largestIndex(array){
var counter = 1;
var max = 0;
for(counter; counter < array.length; counter++){
if(array[max] < array[counter]){
max = counter;
}
}
return max;
}
console.log("index with largest value is: " +largestIndex(mountains));
// index with largest value is: 3
To complete the work of @VFDan, I benchmarked the 3 methods: the accepted one (custom loop), reduce, and find(max(arr)) on an array of 10000 floats.
If you need your code to run fast, don't use indexOf(max). reduce is ok but use the custom loop if you need the best performances.
You can run this benchmark on other browser using this link: https://jsben.ch/wkd4c
In one line and probably faster then arr.indexOf(Math.max.apply(Math, arr))
:
var a = [0, 21, 22, 7];_x000D_
var indexOfMaxValue = a.reduce((iMax, x, i, arr) => x > arr[iMax] ? i : iMax, 0);_x000D_
_x000D_
document.write("indexOfMaxValue = " + indexOfMaxValue); // prints "indexOfMaxValue = 2"
_x000D_
Where:
iMax
- the best index so far (the index of the max element so far, on the first iteration iMax = 0
because the second argument to reduce()
is 0
, we can't omit the second argument to reduce()
in our case)x
- the currently tested element from the arrayi
- the currently tested indexarr
- our array ([0, 21, 22, 7]
)About the reduce()
method (from "JavaScript: The Definitive Guide" by David Flanagan):
reduce() takes two arguments. The first is the function that performs the reduction operation. The task of this reduction function is to somehow combine or reduce two values into a single value, and to return that reduced value.
Functions used with reduce() are different than the functions used with forEach() and map(). The familiar value, index, and array values are passed as the second, third, and fourth arguments. The first argument is the accumulated result of the reduction so far. On the first call to the function, this first argument is the initial value you passed as the second argument to reduce(). On subsequent calls, it is the value returned by the previous invocation of the function.
When you invoke reduce() with no initial value, it uses the first element of the array as the initial value. This means that the first call to the reduction function will have the first and second array elements as its first and second arguments.
var arr=[0,6,7,7,7];_x000D_
var largest=[0];_x000D_
//find the largest num;_x000D_
for(var i=0;i<arr.length;i++){_x000D_
var comp=(arr[i]-largest[0])>0;_x000D_
if(comp){_x000D_
largest =[];_x000D_
largest.push(arr[i]);_x000D_
}_x000D_
}_x000D_
alert(largest )//7_x000D_
_x000D_
//find the index of 'arr'_x000D_
var arrIndex=[];_x000D_
for(var i=0;i<arr.length;i++){_x000D_
var comp=arr[i]-largest[0]==0;_x000D_
if(comp){_x000D_
arrIndex.push(i);_x000D_
}_x000D_
}_x000D_
alert(arrIndex);//[2,3,4]
_x000D_
Unless I'm mistaken, I'd say it's to write your own function.
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;
}
If you create a copy of the array and sort it descending, the first element of the copy will be the largest. Than you can find its index in the original array.
var sorted = [...arr].sort((a,b) => b - a)
arr.indexOf(sorted[0])
Time complexity is O(n) for the copy, O(n*log(n)) for sorting and O(n) for the indexOf.
If you need to do it faster, Ry's answer is O(n).
reduce
:[1,2,5,0,4].reduce((a,b,i) => a[0] < b ? [b,i] : a, [Number.MIN_VALUE,-1])
//[5,2]
This returns [5e-324, -1]
if the array is empty. If you want just the index, put [1]
after.
>
and MAX_VALUE
):[1,2,5,0,4].reduce((a,b,i) => a[0] > b ? [b,i] : a, [Number.MAX_VALUE,-1])
//[0, 3]
Source: Stackoverflow.com