Mam to:
var arr = [0, 21, 22, 7];
Jaki jest najlepszy sposób na zwrócenie indeksu o najwyższej wartości do innej zmiennej?
javascript
arrays
max
Stephen
źródło
źródło
arr.indexOf(Math.max(...arr))
to też moja odpowiedź, ale funkcja).Odpowiedzi:
To prawdopodobnie najlepszy sposób, ponieważ jest niezawodny i działa na starych przeglądarkach:
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; }
Jest też jedna linijka:
let i = arr.indexOf(Math.max(...arr));
Wykonuje dwa razy więcej porównań, niż jest to konieczne, i będzie jednak
RangeError
generować duże tablice. Trzymałbym się funkcji.źródło
const max = arr.reduce((m, n) => Math.max(m, n))
, a następnie indeksy maksimum to[...arr.keys()].filter(i => arr[i] === max)
.[...arr.keys()]
wyświetla błąd:unexpected token
W jednej linii i prawdopodobnie szybciej
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"
Gdzie:
iMax
- najlepszy jak dotąd indeks (jak dotąd indeks elementu max, w pierwszej iteracji,iMax = 0
ponieważ drugi argument doreduce()
to0
, nie możemyreduce()
w naszym przypadku pominąć drugiego argumentu do )x
- aktualnie testowany element z tablicyi
- aktualnie testowany indeksarr
- nasza tablica ([0, 21, 22, 7]
)O
reduce()
metodzie (z „JavaScript: The Definitive Guide” Davida Flanagana):źródło
arr.reduce((bestIndexSoFar, currentlyTestedValue, currentlyTestedIndex, array) => currentlyTestedValue > array[bestIndexSoFar] ? currentlyTestedIndex : bestIndexSoFar, 0);
, który można określić jako: iteracji tablica rozpoczynając od indeksu parametrów 0 (2), jeżeli currentlyTestedValue jest wyższa od wartości elementu w bestIndexSoFar , a następnie powrócić do currentlyTestedIndex do następnej iteracji jako bestIndexSoFar .this.methods.reduce((methodIndex, currentMethod, currentMethodIndex, methods) => currentMethod.price <= methods[methodIndex].price ? currentMethodIndex : methodIndex, 0)
.Oto inne rozwiązanie, jeśli używasz ES6 z operatorem spreadu:
var arr = [0, 21, 22, 7]; const indexOfMaxValue = arr.indexOf(Math.max(...arr));
źródło
Kolejne rozwiązanie wykorzystujące max
reduce
:[1,2,5,0,4].reduce((a,b,i) => a[0] < b ? [b,i] : a, [Number.MIN_VALUE,-1]) //[5,2]
Zwraca,
[5e-324, -1]
jeśli tablica jest pusta. Jeśli potrzebujesz tylko indeksu, wstaw[1]
po.Min przez (Zmień na
>
iMAX_VALUE
):[1,2,5,0,4].reduce((a,b,i) => a[0] > b ? [b,i] : a, [Number.MAX_VALUE,-1]) //[0, 3]
źródło
O ile się nie mylę, powiedziałbym, że chodzi o napisanie własnej funkcji.
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; }
źródło
findIndexOfGreatest( [-5, 0, -10, -1])
zwraca 3 ...Jeśli używasz podkreślenia, możesz użyć tego ładnego krótkiego, jednowierszowego:
Najpierw znajdzie wartość największego elementu w tablicy, w tym przypadku 22. Następnie zwróci indeks miejsca, w którym 22 znajduje się w tablicy, w tym przypadku 2.
źródło
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; }
przejść
array
dohaystack
iMath.max(...array)
doneedle
. To da wszystkie maksymalne elementy tablicy i jest bardziej rozszerzalne (na przykład musisz również znaleźć wartości minimalne)źródło
Aby zakończyć pracę @VFDan, przeprowadziłem testy porównawcze 3 metod: zaakceptowaną (pętla niestandardowa), redukuj i znajdź (max (arr)) na tablicy 10000 wartości zmiennoprzecinkowych.
Wyniki na Chromeimum 85 Linux (im wyższy, tym lepszy):
Wyniki w przeglądarce Firefox 80 Linux (im wyższa, tym lepsza):
Wniosek:
Jeśli chcesz, aby Twój kod działał szybko, nie używaj indexOf (max). Redukcja jest w porządku, ale użyj niestandardowej pętli, jeśli potrzebujesz najlepszych wyników.
Możesz uruchomić ten test porównawczy w innej przeglądarce, korzystając z tego linku: https://jsben.ch/wkd4c
źródło
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]
źródło
EDYCJA: Wiele lat temu podałem odpowiedź, która była obrzydliwa, zbyt szczegółowa i zbyt skomplikowana. Więc go edytuję. Preferuję powyższe odpowiedzi funkcjonalne ze względu na ich zgrabny czynnik, ale nie za ich czytelność; ale gdybym był bardziej zaznajomiony z javascriptem, to też by mi się spodobały.
Pseudo kod:
Indeks śledzenia zawierający największą wartość. Załóżmy, że indeks 0 jest początkowo największy. Porównaj z bieżącym indeksem. W razie potrzeby zaktualizuj indeks z największą wartością.
Kod:
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
źródło
Jeśli utworzysz kopię tablicy i posortujesz ją malejąco, pierwszy element kopii będzie największy. Niż możesz znaleźć jego indeks w oryginalnej tablicy.
var sorted = [...arr].sort((a,b) => b - a) arr.indexOf(sorted[0])
Złożoność czasowa wynosi O (n) dla kopii, O (n * log (n)) dla sortowania i O (n) dla indexOf.
Jeśli chcesz to zrobić szybciej, odpowiedź Ry to O (n).
źródło
Stabilna wersja tej funkcji wygląda następująco:
// 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; }
źródło