Reputation: 2851
I have an example array:
var arr = [10, 67, 100, 100];
I want to find the indexes of the maximum values in the array.
This function finds only one index:
function max(arr) {
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;
}
How can I modify it to return an array of max indexes? In the example array above, it should return
[2, 3]
.
Upvotes: 6
Views: 4877
Reputation: 179
This is solution when you find max value at fist and then indexes of all max values.
function multipleMax(arr){
var maxvalue = Math.max(...arr);
var maxIndexes = [];
for(i = 0; i < arr.length; i++){
if(arr[i] == maxvalue){
maxIndexes.push(i);};
};
return maxIndexes;
};
var arr = [10, 67, 100, 100];
console.log(multipleMax(arr));
Upvotes: 0
Reputation: 26161
I would do like this;
var arr = [10, 67, 100, 100],
m = Math.max(...arr),
maxes = arr.reduce((p,c,i,a) => c == m ? p.concat(i) : p,[]);
console.log(maxes);
Upvotes: 2
Reputation: 901
JS's Reduce can help with this task.
// Finds maximum value across entire array
var maxArrSingle = function(arr) {
return arr.reduce(
function(acc,val){
return Math.max(acc,val);
},
-Infinity);
}
// Find indices where array is at max
var maxArrIndexes = function(arr) {
var max = maxArrSingle(arr);
return arr.reduce(function(acc,val,idx) {
if (val >= max) acc.push(idx);
return acc;
},[]);
}
// demos
var arr = [10, 67, 100, 100];
console.log(maxArrIndexes(arr));
var arr = [-10, -67, -100, -100, -4000, -9, -90, -90 ];
console.log(maxArrIndexes(arr));
var arr = [];
console.log(maxArrIndexes(arr));
var arr = [0];
console.log(maxArrIndexes(arr));
var arr = [0,0];
console.log(maxArrIndexes(arr));
Upvotes: 0
Reputation: 20228
Based on this runtime comparison, I propose searching for the max indices via optimized for-loop:
function max(arr) {
var max = -Infinity, indices = [];
for (var i = 0; i < arr.length; ++i) {
if (arr[i] < max) continue;
if (arr[i] > max) {
indices = [];
max = arr[i];
}
indices.push(i);
}
return indices;
}
console.log(max([10, 67, 100, 100])); // [2, 3]
Comparing against arr[i] < max
first is useful since it evaluates to true most of the time and thus enables us to skip to the next iteration with only 1 array access + comparison on average.
Runtime comparison of the different proposed algorithms:
According to https://jsfiddle.net/jv1z29jm/2/ - please feel free to update.
Chrome (48):
max_indexOf x 15,381 ops/sec ±2.94% (87 runs sampled)
max_reduce x 2,909 ops/sec ±2.63% (86 runs sampled)
max_forloop x 119,964 ops/sec ±1.80% (87 runs sampled)
max_forloopOptimized x 165,581 ops/sec ±1.50% (87 runs sampled)
Fastest is max_forloopOptimized
Firefox (46):
max_indexOf x 56,456 ops/sec ±0.74% (67 runs sampled)
max_reduce x 74,959 ops/sec ±0.86% (65 runs sampled)
max_forloop x 73,223 ops/sec ±24.75% (58 runs sampled)
max_forloopOptimized x 84,567 ops/sec ±9.99% (61 runs sampled)
Fastest is max_forloopOptimized
Upvotes: 0
Reputation: 60143
Instead of keeping track of just one index, you'll need to keep track of all indices. Give this a try:
function max(arr) {
var max = -Infinity;
var maxIndices = [];
for (var i = 0; i < arr.length; i++) {
if (arr[i] === max) {
maxIndices.push(i);
} else if (arr[i] > max) {
maxIndices = [i];
max = arr[i];
}
}
return maxIndices;
}
Upvotes: 3
Reputation: 7131
function max(arr) {
var largest = Math.max.apply(Math, arr);
var indexes = [], i = -1;
while ((i = arr.indexOf(largest, i+1)) != -1){
indexes.push(i);
}
return indexes;
}
var arr = [10, 67, 100, 100];
console.log(max(arr));
Upvotes: 1