Eu tenho isto:
var arr = [0, 21, 22, 7];
Qual é a melhor maneira de retornar o índice do valor mais alto para outra variável?
Eu tenho isto:
var arr = [0, 21, 22, 7];
Qual é a melhor maneira de retornar o índice do valor mais alto para outra variável?
Respostas:
Esta é provavelmente a melhor maneira, pois é confiável e funciona em navegadores antigos:
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;
}
Há também este one-liner:
let i = arr.indexOf(Math.max(...arr));
Ele realiza o dobro de comparações necessárias e, RangeError
no entanto, gera uma matriz grande. Eu manteria a função.
const max = arr.reduce((m, n) => Math.max(m, n))
, então os índices do máximo são [...arr.keys()].filter(i => arr[i] === max)
.
[...arr.keys()]
gera um erro:unexpected token
Em uma linha e provavelmente mais rápido que 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"
Onde:
iMax
- o melhor índice até agora (o índice do elemento max até o momento, na primeira iteração iMax = 0
porque o segundo argumento reduce()
é 0
, não podemos omitir o segundo argumento reduce()
no nosso caso)x
- o elemento atualmente testado da matrizi
- o índice atualmente testadoarr
- nossa matriz ( [0, 21, 22, 7]
)Sobre o reduce()
método (de "JavaScript: The Definitive Guide", de David Flanagan):
reduzir () leva dois argumentos. A primeira é a função que executa a operação de redução. A tarefa dessa função de redução é de alguma forma combinar ou reduzir dois valores em um único valor e retornar esse valor reduzido.
As funções usadas com reduzir () são diferentes das funções usadas com forEach () e mapa (). O valor familiar, o índice e os valores da matriz são passados como segundo, terceiro e quarto argumentos. O primeiro argumento é o resultado acumulado da redução até o momento. Na primeira chamada para a função, esse primeiro argumento é o valor inicial que você passou como o segundo argumento para reduzir (). Nas chamadas subseqüentes, é o valor retornado pela chamada anterior da função.
Quando você invoca reduzir () sem valor inicial, ele usa o primeiro elemento da matriz como valor inicial. Isso significa que a primeira chamada para a função de redução terá o primeiro e o segundo elementos da matriz como primeiro e segundo argumentos.
arr.reduce((bestIndexSoFar, currentlyTestedValue, currentlyTestedIndex, array) => currentlyTestedValue > array[bestIndexSoFar] ? currentlyTestedIndex : bestIndexSoFar, 0);
, o que pode ser descrito como: iterar a matriz a partir de índice 0 (segundo parâmetro), se currentlyTestedValue é maior do que o valor do elemento no bestIndexSoFar , em seguida, voltar a currentlyTestedIndex para a iteração seguinte como a bestIndexSoFar .
this.methods.reduce((methodIndex, currentMethod, currentMethodIndex, methods) => currentMethod.price <= methods[methodIndex].price ? currentMethodIndex : methodIndex, 0)
.
Aqui está outra solução: se você estiver usando o ES6 usando o operador spread:
var arr = [0, 21, 22, 7];
const indexOfMaxValue = arr.indexOf(Math.max(...arr));
A menos que eu esteja enganado, eu diria que é escrever sua própria função.
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]
Isso retorna [5e-324, -1]
se a matriz estiver vazia. Se você quiser apenas o índice, coloque[1]
depois.
>
e MAX_VALUE
):[1,2,5,0,4].reduce((a,b,i) => a[0] > b ? [b,i] : a, [Number.MAX_VALUE,-1])
//[0, 3]
Edição: Anos atrás, eu dei uma resposta para isso que era nojento, específico demais e complicado demais. Então, eu estou editando. Eu sou a favor das respostas funcionais acima por seu fator elegante, mas não por sua legibilidade; mas se eu estivesse mais familiarizado com o javascript, talvez também gostasse deles.
Pseudo-código:
Índice de faixas que contém o maior valor. Suponha que o índice 0 seja o maior inicialmente. Compare com o índice atual. Atualize o índice com o maior valor, se necessário.
Código:
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;
}
passar array
para haystack
e Math.max(...array)
para needle
. Isso fornecerá todos os elementos máximos da matriz e é mais extensível (por exemplo, você também precisa encontrar valores mínimos)
Se você criar uma cópia da matriz e ordená-la em ordem decrescente, o primeiro elemento da cópia será o maior. Do que você pode encontrar o seu índice na matriz original.
var sorted = [...arr].sort((a,b) => b - a)
arr.indexOf(sorted[0])
A complexidade de tempo é O (n) para a cópia, O (n * log (n)) para classificação e O (n) para o indexOf.
Se você precisar fazer isso mais rapidamente, a resposta de 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]
Uma versão estável desta função é semelhante a esta:
// 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;
}
Simples
maxarr: function(){
let maxval = 0;
let maxindex = null;
for (i = 0; i < arr.length; i++){
if (arr[i] > maxval) {
maxval = arr[i];
maxindex = i;
}
}
}