Índice de retorno de maior valor em uma matriz
Qual é a melhor maneira de retornar o índice do valor mais alto para outra variável?
Isso não é uma cópia, leia a pergunta… @Dancrumb A maneira como o SO funciona é que eu posto essa pergunta e, nas próximas décadas, as pessoas a encontrarão, lerão e serão gratas pelas informações que os colaboradores postaram abaixo!
@ Stephen, pelo contrário, se você ler esta FAQ , verá que perguntas subjetivas (como as que começam com "Qual é a melhor maneira ...") são expressamente desencorajadas. No entanto, o SO é uma comunidade, portanto cabe à comunidade determinar se essa pergunta deve ser encerrada ou não.
Encontrar o maior número em uma matriz não é o mesmo que encontrar o índice do maior número em uma matriz. Portanto, esta pergunta não é uma duplicata dessa referência publicada como duplicada.
— Fzs2
Esta NÃO é uma duplicata - ou pelo menos não é da questão referenciada. Eu não consigo entender os votos negativos sobre isso - dizer que você não pode perguntar a SO, a melhor maneira de fazer algo é ridículo, e nenhum exemplo de código é necessário para uma pergunta tão concisa. Como é que o 'duplicado' referenciado tem +30 votos, e essa pergunta paralela MAS DIFERENTE, feita de maneira muito semelhante, tem -3 votos? Releia a pergunta e remova seus votos marcados como duplicados. "índice de" é a frase-chave que você precisa identificar no título da pergunta.
@Dancrumb Os conselhos atuais em stackoverflow.com/help/dont-ask desencorajam perguntas subjetivas apenas se todas as respostas forem igualmente válidas. Nesse caso, o "melhor" pode ser claramente avaliado em termos de desempenho, concisão e expressividade.
Esta é provavelmente a melhor maneira, pois é confiável e funciona em navegadores antigos:
Há também este one-liner:
let i = arr.indexOf(Math.max(...arr));
Ele realiza o dobro de comparações necessárias e, RangeErrorno entanto, gera uma matriz grande. Eu manteria a função.
Ok, esta função retorna o primeiro índice encontrado para o maior valor. Digamos que eu tenha mais de um índice com o mesmo valor mais alto, como obtenho todos esses índices?
— Ed1nh0 15/04/19
@ ed1nh0: A maneira mais fácil é fazer vários passes. Encontre o máximo com 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
— ed1nh0 22/04/19
@ ed1nh0: Qual navegador / ambiente você está alvejando?
Cromada. Estou usando o VueJS e acho que o problema está relacionado à configuração do webpack.
— Ed1nh0 24/04/19
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"
iMax- o melhor índice até agora (o índice do elemento max até o momento, na primeira iteração iMax = 0porque o segundo argumento reduce()é 0, não podemos omitir o segundo argumento reduce()no nosso caso)
x - o elemento atualmente testado da matriz
i - o índice atualmente testado
arr- 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.
— traxium
@traxium Embora a sua explicação seja ótima, o exemplo poderia ser mais claro para aqueles que menos entendem de programação funcional se usarmos variáveis ​​mais descritivas. Diga: 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 .
— Niieani 14/10/2015
@traxium Resposta impressionante. Concordo também com @niieani Aqui está um exemplo do mundo real Eu implementados: this.methods.reduce((methodIndex, currentMethod, currentMethodIndex, methods) => currentMethod.price <= methods[methodIndex].price ? currentMethodIndex : methodIndex, 0).
@ DanielK, a resposta com os nomes de parâmetro "completos" não caberia em uma linha de fluxo de pilha. Apareceria uma barra de rolagem horizontal e não seria muito conveniente ler o trecho enquanto rolava horizontalmente. De qualquer forma, obrigado pelas sugestões. Eu editei a resposta de outra maneira.
@traxium +1 para uma solução FP. Embora seja morbidamente complexo para alguém que está começando com o JS, sua solução também é uma das de maior desempenho para solucionar o problema do OP.
De acordo com jsben.ch/ujXlk , o outro método é mais rápido.
— VFDan 18/02
Aqui está outra solução: se você estiver usando o ES6 usando o operador spread:
const indexOfMaxValue = arr.indexOf(Math.max(...arr));
— Lanil Marasinghe
A menos que eu esteja enganado, eu diria que é escrever sua própria função.
Se você estiver utilizando sublinhado, poderá usar esta bela linha curta:
_.indexOf(arr, _.max(arr))
Ele primeiro encontrará o valor do maior item da matriz, neste caso 22. Em seguida, retornará o índice de onde 22 está dentro da matriz, neste caso 2.
Outra solução do max usando 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.
Min via (Alterar para >e MAX_VALUE):
[1,2,5,0,4].reduce((a,b,i) => a[0] > b ? [b,i] : a, [Number.MAX_VALUE,-1])
//[0, 3]
— randompast
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.
Í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.
var mountains = [3, 1, 5, 9, 4];
function largestIndex(array){
for(counter; counter < array.length; counter++){
if(array[max] < array[counter]){
console.log("index with largest value is: " +largestIndex(mountains));
// index with largest value is: 3
— Ross Studtman
Obrigado! Eu tive que mexer com isso ainda mais.
function findIndicesOf(haystack, needle)
for (var i = 0; i < haystack.length; ++i) {
passar arraypara haystacke 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)
— Edward Karak
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).
— rodurico
var arr=[0,6,7,7,7];
var largest=[0];
//find the largest num;
var comp=(arr[i]-largest[0])>0;
largest =[];
alert(largest )//7
//find the index of 'arr'
var arrIndex=[];
var comp=arr[i]-largest[0]==0;
arrIndex.push(i);
alert(arrIndex);//[2,3,4]
— mos wen
Uma versão estável desta função é semelhante a esta:
// not defined for empty array
function max_index(elements) {
while (i < elements.length) {
if (!(elements[i] < elements[mi]))
O que significa "estável" neste contexto?
Eu acho que ele quis dizer "adequado"
— Ikbel 18/12/16
maxarr: function(){
let maxindex = null;
if (arr[i] > maxval) {
— vidhyesh
Desculpe ENTENDI't claramente ler o post agora eu vou atualizar o código
por favor, explique um pouco mais a sua resposta (ajuda a remover os votos negativos) e tente diferenciá-la de outra resposta (ieeg: usando menos recursos ou é mais rápido no cálculo ... etc). (Fim da revisão da resposta de baixa qualidade).