배열에서 가장 큰 값의 인덱스를 반환


139

나는 이것을 가지고있다:

var arr = [0, 21, 22, 7];

가장 높은 값의 인덱스를 다른 변수에 반환하는 가장 좋은 방법은 무엇입니까?


21
@Dancrumb SO가 작동하는 방식은이 질문을 게시하는 것입니다. 수십 년 동안 사람들이이 질문을 찾고, 읽고, 기고자들이 아래에 게시 한 정보에 대해 감사 할 것입니다!
Stephen

1
@Stephen은 반대로이 FAQ 를 읽으면 주관적인 질문 (예 : "최상의 방법은 무엇입니까?"으로 시작하는 질문)이 명시 적으로 권장되지 않음을 알 수 있습니다. 그러나 SO는 커뮤니티이므로 커뮤니티에서이 질문을 닫을 지 여부를 결정해야합니다.
Dancrumb

6
배열에서 가장 큰 숫자를 찾는 것은 배열에서 가장 큰 숫자의 인덱스를 찾는 것과 다릅니다. 따라서이 질문은 중복으로 게시 된 해당 참조의 사본이 아닙니다.
Fzs2

15
이것은 중복이 아니거나 적어도 언급 된 질문과는 다릅니다. 나는 이것에 대한 downvotes를 이해할 수 없다-당신이 그렇게 할 수있는 최선의 방법은 어리석은 것이며, 그러한 간결한 질문에는 코드 예제가 필요하지 않다고 말하는 것입니다. 참조 된 '중복'에 +30 표가 있고, 이와 비슷한 방식으로 질문되는 이와 유사한 다른 질문이 -3 표에 어떻게 해당됩니까? 질문을 다시 읽고 중복 된 것으로 표시된 투표를 제거하십시오. "인덱스"는 질문 제목에서 찾아야하는 핵심 문구입니다.
팬케이크

@Dancrumb stackoverflow.com/help/dont-ask 의 현재 조언은 모든 답변이 똑같이 유효한 경우에만 주관적인 질문을 권장하지 않습니다. 이 경우 성능, 간결함 및 표현력 측면에서 "최고"를 명확하게 평가할 수 있습니다.
user234461 2018 년

답변:


165

신뢰할 수 있고 오래된 브라우저에서 작동하기 때문에 이것이 가장 좋은 방법 일 것입니다.

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하고 큰 배열에서을 발생시킵니다. 나는 그 기능을 고수했다.


1
Ok이 함수는 가장 큰 값을 가진 첫 번째 색인 을 반환 합니다 . 동일한 최고 가치를 가진 둘 이상의 인덱스를 가지고 있다고 가정 해 봅시다.이 모든 인덱스를 어떻게 얻 습니까?
ed1nh0

1
@ ed1nh0 : 쉬운 방법은 여러 번 통과하는 것입니다. 을 사용하여 최대 값을 찾은 다음 최대 값 const max = arr.reduce((m, n) => Math.max(m, n))의 인덱스는 [...arr.keys()].filter(i => arr[i] === max)입니다.
Ry-

[...arr.keys()]오류를 출력합니다 :unexpected token
ed1nh0

@ ed1nh0 : 어떤 브라우저 / 환경을 타겟팅하고 있습니까?
Ry-

크롬. VueJS를 사용하고 있으며 웹 팩 구성에 문제가 있다고 생각합니다.
ed1nh0

82

한 줄에 아마 더 빠를 것입니다 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()메소드 정보 (David Flanagan의 "JavaScript : The Definitive Guide"에서 제공) :

reduce ()는 두 개의 인수를 취합니다. 첫 번째는 축소 작업을 수행하는 기능입니다. 이 축소 기능의 임무는 어떻게 든 두 값을 단일 값으로 결합하거나 줄이고 그 감소 된 값을 반환하는 것입니다.

reduce ()에 사용 된 함수는 forEach () 및 map ()에 사용 된 함수와 다릅니다. 익숙한 값, 인덱스 및 배열 값이 두 번째, 세 번째 및 네 번째 인수로 전달됩니다. 첫 번째 주장은 지금까지 축소 된 누적 결과입니다. 함수에 대한 첫 번째 호출에서이 첫 번째 인수는 reduce ()에 대한 두 번째 인수로 전달한 초기 값입니다. 후속 호출에서는 이전 함수 호출에서 리턴 된 값입니다.

초기 값없이 reduce ()를 호출하면 배열의 첫 번째 요소를 초기 값으로 사용합니다. 이는 감소 함수에 대한 첫 번째 호출이 첫 번째 및 두 번째 배열 요소를 첫 번째 및 두 번째 인수로 갖게됨을 의미합니다.


12
@traxium 당신의 설명은 훌륭하지만, 더 많은 설명 변수를 사용하면 기능 프로그래밍에 덜 익숙한 사람들에게는 예제가 더 명확해질 수 있습니다. 인사 : arr.reduce((bestIndexSoFar, currentlyTestedValue, currentlyTestedIndex, array) => currentlyTestedValue > array[bestIndexSoFar] ? currentlyTestedIndex : bestIndexSoFar, 0);으로 기재 될 수있다 : 만약 반복 처리는 인덱스 0 (2 파라미터)에서 시작하여 배열 currentlyTestedValue는 상기 요소의 값보다 높은 bestIndexSoFar 후 리턴 currentlyTestedIndex을 는 AS 다음 반복에 bestIndexSoFar .
niieani

1
@traxium 멋진 답변입니다. 또한 @niieani에 동의합니다 this.methods.reduce((methodIndex, currentMethod, currentMethodIndex, methods) => currentMethod.price <= methods[methodIndex].price ? currentMethodIndex : methodIndex, 0). 구현 한 실제 예는 다음과 같습니다 ..
Daniel

2
@DanielK, "full"매개 변수 이름을 가진 답은 하나의 stackoverflow 행에 맞지 않습니다. 가로 스크롤 막대가 나타나고 가로로 스크롤하는 동안 스 니펫을 읽는 것이 매우 편리하지 않습니다. 어쨌든 제안에 감사드립니다. 다른 방법으로 답변을 편집했습니다.
traxium

FP 솔루션의 경우 @traxium +1 JS로 시작하는 사람에게는 병적으로 복잡하지만 귀하의 솔루션은 OP의 문제를 해결하는 데 가장 우수한 솔루션 중 하나입니다.
SeaWarrior404

jsben.ch/ujXlk 에 따르면 다른 방법이 더 빠릅니다.
VFDan

47

스프레드 연산자를 사용하여 ES6을 사용하는 경우 다른 솔루션이 있습니다.

var arr = [0, 21, 22, 7];

const indexOfMaxValue = arr.indexOf(Math.max(...arr));

6

내가 실수하지 않는 한, 나는 당신 자신의 기능을 작성해야한다고 말하고 싶습니다.

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;
}

6

밑줄을 사용하는 경우이 멋진 짧은 원 라이너를 사용할 수 있습니다.

_.indexOf(arr, _.max(arr))

먼저 배열에서 가장 큰 항목 (이 경우 22)의 값을 찾습니다. 그런 다음 배열에서 22가있는 배열의 인덱스 (이 경우 2)를 리턴합니다.


6

max를 사용하는 또 다른 솔루션 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]

1

편집 : 몇 년 전에 나는 거칠고 너무 구체적이며 너무 복잡한 이것에 대한 대답을했습니다. 편집하고 있습니다. 나는 그들의 깔끔한 요소에 대해서는 위의 기능적 답변을 선호하지만 가독성은 좋지 않습니다. 그러나 내가 자바 스크립트에 더 익숙하다면 나도 그것을 좋아할 것입니다.

의사 코드 :

가장 큰 값을 포함하는 색인을 추적하십시오. 인덱스 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

감사! 나는 그것을 더 엉망으로 만들어야했습니다.
로스 스터 트맨

1
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;
}

통과 arrayhaystackMath.max(...array)needle. 그러면 배열의 모든 최대 요소 가 제공 되며 확장 성이 더 뛰어납니다 (예 : 최소값도 찾아야 함)


1

배열의 복사본을 만들어 내림차순으로 정렬하면 복사본의 첫 번째 요소가 가장 큽니다. 원래 배열에서 색인을 찾을 수 있습니다.

var sorted = [...arr].sort((a,b) => b - a)
arr.indexOf(sorted[0])

시간 복잡도는 사본의 경우 O (n), 정렬의 경우 O (n * log (n)), indexOf의 경우 O (n)입니다.

더 빨리해야한다면 Ry의 대답은 O (n)입니다.


0

 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]


-1

이 함수의 안정적인 버전은 다음과 같습니다.

// 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;
}

이 맥락에서 "안정적"은 무엇을 의미합니까?
Ry-

나는 그가 "적합한"을 의미한다고 생각한다
Ikbel

-5

단순한

maxarr: function(){
let maxval = 0;
let maxindex = null;
for (i = 0; i < arr.length; i++){
if (arr[i] > maxval) {
maxval = arr[i];
maxindex = i;
}
}
}

죄송합니다, 지금 글을 읽지 못했습니다. 코드를 업데이트하겠습니다.
vidhyesh

답을 조금 더 설명하고 (다운 보트를 제거하는 데 도움이 됨) 다른 답과 차별화하도록 노력하십시오 (예 : 적은 자원을 사용하거나 계산 속도가 빠릅니다 ... 등). (품질이 낮은 답변 검토 종료).
ZF007

최대 값 의 인덱스 는 반환하지 않습니다 . 최대 양수 값만 반환합니다 .
Cœur
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.