У меня есть это:
var arr = [0, 21, 22, 7];
Каков наилучший способ вернуть индекс наибольшего значения в другую переменную?
У меня есть это:
var arr = [0, 21, 22, 7];
Каков наилучший способ вернуть индекс наибольшего значения в другую переменную?
Ответы:
Это, вероятно, лучший способ, поскольку он надежен и работает на старых браузерах:
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;
}
Также есть однострочный:
let i = arr.indexOf(Math.max(...arr));
Он выполняет в два раза больше сравнений, чем необходимо, и RangeError
, тем не менее, будет вызывать большие массивы. Я бы придерживался функции.
const max = arr.reduce((m, n) => Math.max(m, n))
, тогда индексы максимума равны [...arr.keys()].filter(i => arr[i] === max)
.
[...arr.keys()]
выводит ошибку: unexpected token
Одной строкой и, возможно, быстрее 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"
Куда:
iMax
- лучший индекс на данный момент (индекс максимального элемента на первой итерации, iMax = 0
потому что второй аргумент reduce()
равен 0
, мы не можем пропустить второй аргумент reduce()
в нашем случае)x
- текущий проверенный элемент из массиваi
- текущий протестированный индексarr
- наш массив ( [0, 21, 22, 7]
)О reduce()
методе (из «JavaScript: Полное руководство» Дэвида Фланагана):
reduce () принимает два аргумента. Первая - это функция, выполняющая операцию сокращения. Задача этой функции сокращения - каким-то образом объединить или уменьшить два значения в одно значение и вернуть это уменьшенное значение.
Функции, используемые с reduce (), отличаются от функций, используемых с forEach () и map (). Знакомое значение, индекс и значения массива передаются как второй, третий и четвертый аргументы. Первый аргумент - это накопленный к настоящему моменту результат сокращения. При первом вызове функции этот первый аргумент - это начальное значение, которое вы передали в качестве второго аргумента функции reduce (). При последующих вызовах это значение, возвращаемое предыдущим вызовом функции.
Когда вы вызываете reduce () без начального значения, он использует первый элемент массива в качестве начального значения. Это означает, что первый вызов функции сокращения будет иметь первый и второй элементы массива в качестве первого и второго аргументов.
arr.reduce((bestIndexSoFar, currentlyTestedValue, currentlyTestedIndex, array) => currentlyTestedValue > array[bestIndexSoFar] ? currentlyTestedIndex : bestIndexSoFar, 0);
, которая может быть описана как: итерация массива , начиная с индекса 0 (второй параметр), если currentlyTestedValue выше , чем значение элемента в bestIndexSoFar , а затем вернуть currentlyTestedIndex к следующей итерации в качестве bestIndexSoFar .
this.methods.reduce((methodIndex, currentMethod, currentMethodIndex, methods) => currentMethod.price <= methods[methodIndex].price ? currentMethodIndex : methodIndex, 0)
.
Вот еще одно решение, если вы используете ES6 с оператором распространения:
var arr = [0, 21, 22, 7];
const indexOfMaxValue = arr.indexOf(Math.max(...arr));
Если не ошибаюсь, я бы сказал, чтобы написать свою функцию.
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;
}
reduce
:[1,2,5,0,4].reduce((a,b,i) => a[0] < b ? [b,i] : a, [Number.MIN_VALUE,-1])
//[5,2]
Это возвращается, [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]
РЕДАКТИРОВАТЬ: Несколько лет назад я дал ответ на этот вопрос, который был грубым, слишком конкретным и слишком сложным. Так что редактирую. Я предпочитаю функциональные ответы выше из-за их аккуратности, но не из-за их удобочитаемости; но если бы я был более знаком с javascript, то они мне тоже могли бы понравиться.
Псевдокод:
Отслеживать индекс, который содержит наибольшее значение. Предположим, что индекс 0 является наибольшим изначально. Сравните с текущим индексом. Обновите индекс с наибольшим значением при необходимости.
Код:
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
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;
}
перейти array
к haystack
и Math.max(...array)
к needle
. Это даст все максимальные элементы массива, и он будет более расширяемым (например, вам также нужно найти минимальные значения)
Если вы создадите копию массива и отсортируете ее по убыванию, первый элемент копии будет самым большим. Затем вы можете найти его индекс в исходном массиве.
var sorted = [...arr].sort((a,b) => b - a)
arr.indexOf(sorted[0])
Сложность по времени составляет O (n) для копии, O (n * log (n)) для сортировки и O (n) для indexOf.
Если вам нужно сделать это быстрее, ответ Ry - O (n).
var arr=[0,6,7,7,7];
var largest=[0];
//find the largest num;
for(var i=0;i<arr.length;i++){
var comp=(arr[i]-largest[0])>0;
if(comp){
largest =[];
largest.push(arr[i]);
}
}
alert(largest )//7
//find the index of 'arr'
var arrIndex=[];
for(var i=0;i<arr.length;i++){
var comp=arr[i]-largest[0]==0;
if(comp){
arrIndex.push(i);
}
}
alert(arrIndex);//[2,3,4]
Стабильная версия этой функции выглядит так:
// 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;
}