JavaScript에서 배열의 최소 / 최대 요소 찾기


778

JavaScript 배열의 최소 또는 최대 요소를 쉽게 얻을 수있는 방법은 무엇입니까?

유사 코드 예 :

let array = [100, 0, 50]

array.min() //=> 0
array.max() //=> 100

93
참고 : 새 사용할 수 있습니다 ECMAScript를 6으로 확산 운영자 : (세 개의 점을 ...포함) Math.max()이 같은 : Math.max(...[2, 5, 16, 1]). MDN 문서 에서 내 대답을 참조하십시오 .
totymedli

1
답변을 수락 한 것으로 표시하십시오.
Alex

여기 할 수있는 가장 일반적인 방법의 속도 비교 벤치 마크 : jsben.ch/#/1QuTg
EscapeNetscape

es6은 기본적으로 훌륭합니다! :)
datdinhquoc

ES6없이 Math.max.apply(null, [2,5,16,1])
Tomer

답변:


827

Math.max/ Math.min대신 사용하도록 내장 Array 객체를 보강하는 방법은 다음과 같습니다.

Array.prototype.max = function() {
  return Math.max.apply(null, this);
};

Array.prototype.min = function() {
  return Math.min.apply(null, this);
};

다음은 JSFiddle 입니다.

내장 기능을 보강하면 다른 라이브러리와 충돌 할 수 있으므로 (일부 참조) 배열에 직접 연결 apply하는 것이 더 편할 수 있습니다 Math.xxx().

var min = Math.min.apply(null, arr),
    max = Math.max.apply(null, arr);

또는 브라우저가 ECMAScript 6을 지원한다고 가정 하면 메소드 와 유사한 기능을 하는 스프레드 연산자 를 사용할 수 있습니다 apply.

var min = Math.min( ...arr ),
    max = Math.max( ...arr );

8
@HankH는 : 통과 null또는 Math또는 {}또는 무엇이든 apply()또는 call()결과에 아무런 관계가 없습니다. 내부적으로 Math.max언급해서는 안됩니다 this.
Roatin Marth

31
C # 프로그래머는 강력하게 입력 된 질문이 필요합니다.
ChaosPandion

7
위의 코드로 jQuery 실수를 공유하면 디버깅하는 데 오랜 시간이 걸렸습니다. jquery 배열은 iPad 이외의 모든 장치에서 잘 작동합니다. 배열을 작동하려면 실제 배열로 변환해야했습니다. 어떤 이유로 든 단일 장치에만 영향을 미침Math.max.apply(null, $.makeArray(array));
Forrest

11
제안 된 접근 방식은 스택 프레임에서 O (n) 메모리를 소비하고 결과적으로 큰 배열에서 충돌하기 때문에 다운 투표했습니다. 내 경우에는 약 130000 개의 숫자로 nodejs를 충돌시킬 수 있습니다.
Alexey Timanovsky

14
이와 같은 내장 프로토 타입을 보강하지 마십시오. 다른 라이브러리와의 충돌에 관한 것이 아닙니다. 또한 브라우저 자체 가 미래에 .max또는 .min메소드를 제공 할 가능성에 관한 것이기도합니다 . 완벽하게 현실적인 시나리오 : 이 답변을 사용하십시오. 2016 년, ES7 또는 ES8 사양 Array.maxArray.min. 이 버전과 달리 문자열에서 작동합니다. 미래의 동료는 이제 잘 문서화 된 기본 .max()메소드를 사용 하여 알파벳순으로 최신 문자열을 배열로 가져 오려고하지만 신비롭게 얻습니다 NaN. 몇 시간 후, 그녀는이 코드를 찾고를 실행하고 git blame이름을 저주합니다.
Mark Amery

362
var max_of_array = Math.max.apply(Math, array);

자세한 내용은 http://aaroncrane.co.uk/2008/11/javascript_max_api/를 참조하십시오.


13
차이점은 무엇이며 Math.max.apply(Math, array)그리고 Math.max.apply(null, array)? 블로그는 "... 당신은 또한 다시 max속한 말을 반복해서 말해야 한다 Math..." 라고 말하지만 , ( applyas 의 첫 번째 인수를 설정함으로써) 그렇게하지 않아도됩니다 null.
ziyuang

9
당신처럼 호출하면 @ziyuang Math.max(a,b), Math로 전달 this이로 호출 할 때 동일한 작업을 수행하기 적합 할 수 있습니다, 그래서 값 apply. 그러나 값을 Math.max사용하지 않으므로 this원하는 값을 전달할 수 있습니다.
Oriol

199

큰 배열 (~ 10⁷ 요소)의 경우 Math.minMath.max모두 Node.js.에서 다음과 같은 오류가 발생합니다

RangeError : 최대 호출 스택 크기를 초과했습니다

보다 강력한 솔루션은 모든 요소를 ​​호출 스택에 추가하는 것이 아니라 배열을 전달하는 것입니다.

function arrayMin(arr) {
  return arr.reduce(function (p, v) {
    return ( p < v ? p : v );
  });
}

function arrayMax(arr) {
  return arr.reduce(function (p, v) {
    return ( p > v ? p : v );
  });
}

속도가 걱정된다면 다음 코드가 Math.max.apply컴퓨터 보다 ~ 3 배 빠릅니다 . http://jsperf.com/min-and-max-in-array/2를 참조하십시오 .

function arrayMin(arr) {
  var len = arr.length, min = Infinity;
  while (len--) {
    if (arr[len] < min) {
      min = arr[len];
    }
  }
  return min;
};

function arrayMax(arr) {
  var len = arr.length, max = -Infinity;
  while (len--) {
    if (arr[len] > max) {
      max = arr[len];
    }
  }
  return max;
};

배열에 숫자 대신 문자열이 포함 된 경우 숫자로도 강제 변환해야합니다. 아래 코드는 그렇게하지만 내 컴퓨터에서 코드가 ~ 10 배 느려집니다. http://jsperf.com/min-and-max-in-array/3를 참조하십시오 .

function arrayMin(arr) {
  var len = arr.length, min = Infinity;
  while (len--) {
    if (Number(arr[len]) < min) {
      min = Number(arr[len]);
    }
  }
  return min;
};

function arrayMax(arr) {
  var len = arr.length, max = -Infinity;
  while (len--) {
    if (Number(arr[len]) > max) {
      max = Number(arr[len]);
    }
  }
  return max;
};

할당 minmax마지막 요소에 1 (반복함으로써 감소 while(--len)))
Venugopal

@Venugopal 그렇다면 배열이 비어 있는지 확인하고 +/- Infinity를 반환하는 특별한 검사가 필요합니다.
Linus Unnebäck

2
이상한 ... 링크 된 웹 사이트로 이동했습니다 ... Firefox 51.0.0 / Mac OS X 10.12.0에서 테스트 한 경우 감소 기반 접근 방식이 루프 기반보다 30 % 느립니다 ... 매우 다른 결과
Pierpaolo Cira

2
very different results 당신은) 오년 나중에 이런 짓을
Алексей Лещук에게

1
2019 년 에는 reduce솔루션이 가장 느립니다. 수백만 개의 요소가있는 배열로 작업하더라도 표준 for 루프를 사용하는 것이 좋습니다 . 자세한 내용은 내 대답을 참조하십시오.
totymedli

152

스프레드 연산자 (ES6) 사용

Math.max(...array);  // the same with "min" => Math.min(...array);


8
이 솔루션은 이미 여러 다른 답변에 의해 제공되었습니다 .
totymedli

15
Math.max (... []) =-무한대. hahaha 😂😂😂
David Portabella

@DavidPortabella 왜 그게 웃긴지 잘 모르겠습니다. 그것이 사양에 따라 작동하는 방식입니다 .If no arguments are given, the result is -∞.
Patrick Roberts

3
예, 자바 스크립트 사양이 끔찍하다는 것을 의미했습니다. 숫자가없는 최소값을 계산할 수없는 것은 분명합니다. 스칼라와 같은 다른 더 심각한 프로그래밍 언어에서는 빈 배열의 최소값을 요구하면 예외가 발생합니다.
David Portabella

3
스칼라는 그들이 잘못했다고 말하는 기계가 필요한 사람들을위한 것입니다
thedanotto

106

tl; dr

// For regular arrays:
var max = Math.max(...arrayOfNumbers);

// For arrays with tens of thousands of items:
let max = testArray[0];
for (let i = 1; i < testArrayLength; ++i) {
  if (testArray[i] > max) {
    max = testArray[i];
  }
}

MDN 솔루션

에 공식 MDN 워드 프로세서Math.max() 이미이 문제를 다루고 있습니다 :

다음 함수는 Function.prototype.apply () 를 사용 하여 숫자 형 배열에서 최대 요소를 찾습니다. getMaxOfArray([1, 2, 3])와 동일 Math.max(1, 2, 3)하지만 getMaxOfArray()어떤 크기의 프로그래밍 방식으로 구성된 배열에 사용할 수 있습니다 .

function getMaxOfArray(numArray) {
    return Math.max.apply(null, numArray);
}

또는 새로운 스프레드 연산자 를 사용하면 최대 배열을 얻는 것이 훨씬 쉬워집니다.

var arr = [1, 2, 3];
var max = Math.max(...arr);

배열의 최대 크기

MDN에 따르면apply 및 확산 솔루션은 인수의 최대 수의 제한에서 온 65536의 제한 :

그러나 이런 식으로 적용하면 JavaScript 엔진의 인수 길이 제한을 초과 할 위험이 있습니다. 너무 많은 인수가있는 함수를 적용 한 결과 (수만 개의 인수 이상으로 생각) 엔진마다 다릅니다 ( JavaScriptCore는 하드 코딩 된 인수 한계 65536 ). 동작)이 지정되지 않았습니다. 일부 엔진은 예외가 발생합니다. 더 악의적으로, 다른 사람들은 실제로 적용된 함수에 전달되는 인수의 수를 임의로 제한합니다. 후자의 경우를 설명하기 위해 : 만약 그러한 엔진이 4 개의 인수의 한계를 가지고 있다면 (실제 한계는 물론 상당히 높음), 위의 예제에서 인수 5, 6, 2, 3이 적용되는 것처럼, 전체 배열보다는.

심지어 다른 솔루션에 비해 성능이 좋지 않은 하이브리드 솔루션도 제공합니다. 자세한 내용은 아래 성능 테스트를 참조하십시오.

2019 년의 실제 제한은 콜 스택의 최대 크기입니다 . 최신 Chromium 기반 데스크톱 브라우저의 경우 최소 또는 최대 apply또는 분산 을 찾는 경우 실제로 숫자 배열의 최대 크기는 ~ 120000 입니다. 이 위에 스택 오버플로가 발생하고 다음과 같은 오류가 발생합니다.

RangeError : 최대 호출 스택 크기를 초과했습니다

아래의 스크립트 ( 이 블로그 게시물을 기반으로 함 )를 사용하여 해당 오류를 발견하면 특정 환경의 한계를 계산할 수 있습니다.

경고! 이 스크립트를 실행하려면 시간이 걸리며 시스템 성능에 따라 브라우저 / 시스템 속도가 느려지거나 충돌 할 수 있습니다!

let testArray = Array.from({length: 10000}, () => Math.floor(Math.random() * 2000000));
for (i = 10000; i < 1000000; ++i) {
  testArray.push(Math.floor(Math.random() * 2000000));
  try {
    Math.max.apply(null, testArray);
  } catch (e) {
    console.log(i);
    break;
  }
}

큰 어레이에서의 성능

EscapeNetscape 의 의견 에 대한 테스트를 기반으로 100000 개의 항목이 있는 난수 배열에서만 5 가지 방법을 테스트하는 벤치 마크를 만들었습니다 .

2019 년 결과에 따르면 표준 루프 (BTW에는 크기 제한이 없음)가 가장 빠릅니다. apply스프레드 는 그 뒤를 잇고, 그 후 MDN의 하이브리드 솔루션 reduce이 가장 느리게 진행됩니다.

스프레드가 왜 가장 느리게 진행되는지를 제외하고는 거의 모든 테스트에서 동일한 결과를 얻었습니다.

백만 개의 항목을 갖도록 배열을 강화하면 문제가 발생하기 시작하고 표준 루프가 빠른 솔루션과 reduce느린 것으로 남게됩니다 .

JSPerf 벤치 마크

어레이의 최소 / 최대 항목을 찾기위한 다양한 솔루션에 대한 jsperf.com 벤치 마크 결과

JSBen 벤치 마크

어레이의 최소 / 최대 항목을 찾기위한 다른 솔루션에 대한 jsben.com 벤치 마크 결과

JSBench.me 벤치 마크

어레이의 최소 / 최대 항목을 찾기위한 다른 솔루션에 대한 jsbench.me 벤치 마크 결과

벤치 마크 소스 코드


typescript를 사용하는 경우 표시된대로 스프레드 연산자가 Math.max.apply(Math, arr)'max'호환성 을 위해 컴파일 됩니다.
Simon_Weaver

1
또한 MDN에서 "모두 확산 (...)apply실패하거나 배열이 너무 많은 요소가있는 경우 잘못된 결과를 반환 것 중 하나 [...] 다음은이 문제가없는 솔루션을 줄이기"테스트 크롬, FF, 에지 및 IE11은 것 같다 최대 100k 값의 배열에 좋습니다. (Win10 및 최신 브라우저 : Chrome 110k, Firefox 300k, Edge 400k, IE11 150k에서 테스트).
oriadam

배열이 수천 개의 요소를 가지면 어떻게 될까요?
Slava Fomin II

@SlavaFominII 답변을 확장하여 수천 개의 요소로 구성된 배열을 포괄합니다.
totymedli

68

사용에 대해 나처럼 편집증 경우 Math.max.apply(큰 배열을 부여 할 때 오류가 발생할 수있는 MDN에 따라 ),이 시도 :

function arrayMax(array) {
  return array.reduce(function(a, b) {
    return Math.max(a, b);
  });
}

function arrayMin(array) {
  return array.reduce(function(a, b) {
    return Math.min(a, b);
  });
}

또는 ES6에서 :

function arrayMax(array) {
  return array.reduce((a, b) => Math.max(a, b));
}

function arrayMin(array) {
  return array.reduce((a, b) => Math.min(a, b));
}

익명 함수는 불행하게도 필요한 (대신 사용하고 Math.max.bind(Math)있기 때문에 reduce단지 통과하지 못할 ab그 기능에, 또한 i우리는 우리가 전화를하지 않도록 할 수 있도록하고, 배열 자체에 대한 참조 max뿐만 아니라 이들에.


ES6 예, 왜 돌아 오지 않는 이유가 Math.max(...array)있습니까?
Wojciech Bednarski

@WojciechBednarski 이 페이지 는 스프레드 연산자를 사용하는 것이 배열을에 전달하는 apply것과 동일하므로 동일한 단점 (최대 인수 제한)을 갖는 것으로 보입니다 .
다니엘 벅 마스터

고마워 축소 후 누락 된 대괄호를 바로 잡을 수 있습니다.function arrayMax(array) { return array.reduce(function(a, b) { return Math.max(a, b); }); // <--------- missing ) }
Arkowsky

1
@DanielDietrich 나는 Math.min()값을 지정하지 않고 호출하는 등가를 수행한다고 생각 합니다 Infinity. 그래서이 함수는 reduce(..., Infinity)해당 동작을 일치시키는 데 사용할 수 있습니다 . 빈 배열의 최소값을 가져 오는 것이 오류가 될 수 있기 때문에 (현재와 같이) 예외를 throw하는 것이 좋습니다.
다니엘 벅 마스터

1
지금까지 감소 속도가 가장 느립니다.
Алексей Лещук

40

.apply 인수 값 목록과 함께 가변 함수를 호출하려는 경우에 자주 사용됩니다. 예 :

Math.max([value1[,value2, ...]])함수는 0보다 큰 숫자 중 가장 큰 숫자를 반환합니다.

Math.max(10, 20); // 20
Math.max(-10, -20); // -10
Math.max(-10, 20); // 20

Math.max()방법을 사용하면 배열을 전달할 수 없습니다. 당신이 값 목록이있는 경우 그 중 당신이 가장 큰 얻을 필요가, 당신은 일반적으로 사용하여이 함수를 호출 할 Function.prototype.apply의 () , 예를

Math.max.apply(null, [10, 20]); // 20
Math.max.apply(null, [-10, -20]); // -10
Math.max.apply(null, [-10, 20]); // 20

그러나 ECMAScript 6부터는 스프레드 연산자를 사용할 수 있습니다 .

spread 연산자를 사용하면 여러 인수 (함수 호출) 또는 여러 요소 (배열 리터럴)가 필요한 위치에서 표현식을 확장 할 수 있습니다.

스프레드 연산자를 사용하면 위와 같이 다시 작성할 수 있습니다.

Math.max(...[10, 20]); // 20
Math.max(...[-10, -20]); // -10
Math.max(...[-10, 20]); // 20

variadic 연산자를 사용하여 함수를 호출 할 때 추가 값을 추가 할 수도 있습니다 (예 :

Math.max(...[10, 20], 50); // 50
Math.max(...[-10, -20], 50); // 50

보너스:

Spread 연산자를 사용하면 ES5 push에서 splice, 등 의 조합을 사용하여 명령형 코드로 대체해야하는 상황에서 배열 리터럴 구문을 사용하여 새 배열을 작성할 수 있습니다 .

let foo = ['b', 'c'];
let bar = ['a', ...foo, 'd', 'e']; // ['a', 'b', 'c', 'd', 'e']

1
보너스의 마지막 예는 concat대부분의 프로그래머가 단일 선 스타일을 유지할 수 있기 때문에 사용합니다.
코디 앨런 테일러

31

두 가지 방법이 더 짧고 쉽습니다.

let arr = [2, 6, 1, 0]

방법 1 :

let max = Math.max.apply(null, arr)

방법 2 :

let max = arr.reduce(function(a, b) {
    return Math.max(a, b);
});

배열이 비어 있는지 확인하십시오-당신이 원하지 않는 음의 무한대를 얻게 될 것입니다. 확산 구문 ( 'arr'대신)을 0사용 [0].concat(arr)하거나 사용 하는 것을 선호한다면[0, ...arr]
Simon_Weaver

방법 1에서 null 값을 제외시키는 방법이 있습니까?
bonbon.langes

22

배열 유형을 확장하여 수행하십시오.

Array.max = function( array ){
    return Math.max.apply( Math, array );
};
Array.min = function( array ){
    return Math.min.apply( Math, array );
}; 

에서 힘 입어 여기 (존 레식에 의해)


20

Array여러 요소에 대한 최소값을 찾는 간단한 솔루션 은 Array프로토 타입 함수 를 사용하는 것입니다 reduce.

A = [4,3,-9,-2,2,1];
A.reduce((min, val) => val < min ? val : min, A[0]); // returns -9

또는 JavaScript의 내장 Math.Min () 함수 사용 (@Tenflex 덕분에) :

A.reduce((min,val) => Math.min(min,val), A[0]);

이 설정 minA[0]이어서, 및 검사 용 A[1]...A[n]엄격히 적은 전류를 초과하는지 여부 min. 그렇다면 A[i] < minmin업데이트됩니다 A[i]. 모든 배열 요소가 처리되면 min결과로 반환됩니다.

편집 : 최소값 위치 포함 :

A = [4,3,-9,-2,2,1];
A.reduce((min, val) => val < min._min ? {_min: val, _idx: min._curr, _curr: min._curr + 1} : {_min: min._min, _idx: min._idx, _curr: min._curr + 1}, {_min: A[0], _idx: 0, _curr: 0}); // returns { _min: -9, _idx: 2, _curr: 6 }

3
A.reduce ((min, val) => Math.min (min, val), A [0]); 더 짧은
Tenflex

보너스 질문으로, min값을 반환 할뿐만 아니라 배열에서의 위치를 얻는 방법은 무엇입니까?
stevek

@meshfields-답변을 업데이트했습니다.
Nicolas Lykke Iversen '12

15

다른 사람들은 이미 그것들을 강화시키는 몇 가지 해결책을 제시했습니다 Array.prototype. 이 답변의 모든 I의 희망은 그것이 있어야 여부를 명확하게하는 것이다 Math.min.apply( Math, array )Math.min.apply( null, array ). 그래서 문맥 것은 사용되어야한다 Mathnull?

null에 컨텍스트로 전달 apply하면 컨텍스트는 기본적으로 전역 객체 ( window브라우저의 경우 객체)로 설정됩니다. Math컨텍스트로 객체를 전달하는 것이 올바른 해결책이지만 전달 null에도 해를 끼치 지 않습니다 . 다음 nullMath.max함수를 장식 할 때 문제를 일으킬 수 있는 예입니다 .

// decorate Math.max
(function (oldMax) {
    Math.max = function () {
        this.foo(); // call Math.foo, or at least that's what we want

        return oldMax.apply(this, arguments);
    };
})(Math.max);

Math.foo = function () {
    print("foo");
};

Array.prototype.max = function() {
  return Math.max.apply(null, this); // <-- passing null as the context
};

var max = [1, 2, 3].max();

print(max);

this.foo으로 평가 되기 때문에 위의 예외 window.foo가 발생 undefined합니다. 우리가 교체 할 경우 nullMath예상 문자열 "foo는"이 화면에 인쇄 될 것 같은 상황이 작동합니다 (I이 사용하여 테스트 모질라 코뿔소 ).

아무도 Math.max그렇게 장식하지 않았다고 생각할 수 있습니다 null. 통과 는 문제없이 작동합니다.


2
요점을 알았어. 그러나 왜 누군가가 장식 Foo.staticMethod하고 참조 this할까요? 데코레이터 디자인에서 실수가 아니겠습니까? (물론 그들은했다하지 않는 한 원하는 전역을 참조하고, 원하는 예를 들어, 코뿔소, 사용되는 자바 스크립트 엔진의 독립 유지).
Roatin Marth

1
스펙 은 어떤 지정된 함수가 " 값"을 참조해야하는지 명시 적입니다 (실제로이 문구는 스펙에서 125 번 나타납니다). Math.max사양에 따라 구현 된을 사용하지 않습니다 this. 누군가 Math.max가 그것을 사용하도록 재정의하면 this행동이 사양을 위반하게되어 날카로운 물건을 던져야합니다. 누군가가 Math.max스와 Math.min힐을 대신 할 가능성에 대해 코딩하는 것보다 그 가능성을 코딩해서는 안됩니다 .
Mark Amery

15

그것을하는 또 다른 방법 :

var arrayMax = Function.prototype.apply.bind(Math.max, null);

용법:

var max = arrayMax([2, 5, 1]);

누군가 이것이 어떻게 작동하는지 설명 할 수 있습니까? 이것은 꽤 마약입니다. 내 이해가 정확합니까 : arrayMax는 함수이며 프로토 타입의 속성에 무언가를 바인딩합니까? 이 apply.bind는 무엇이며 모든 프로토 타입에 있습니까?
Sam

당신은 체크 아웃 할 수 있습니다 : benalman.com/news/2012/09/partial-application-in-javascript
sbr

14

대체 방법


Math.minMath.max방법 모두 JS 엔진의 호출 스택에 추가되는 것을 재귀 적 연산, 가장 가능성있는 충돌 항목의 다수를 포함하는 배열은
(더 ~ 10⁷ 품목보다는 사용자의 브라우저에 따라 다름).

Math.max (... Array (1000000) .keys ());

잡히지 않은 RangeError : 최대 호출 스택 크기를 초과했습니다

대신 다음과 같이 사용하십시오.

arr.reduce((max, val) => max > val ? max : val, arr[0])

또는 더 나은 런타임으로 :

function maxValue(arr) {
  let max = arr[0];

  for (let val of arr) {
    if (val > max) {
      max = val;
    }
  }
  return max;
}

또는 Min과 Max를 모두 얻으려면 :

function getMinMax(arr) {
  return arr.reduce(({min, max}, v) => ({
    min: min < v ? min : v,
    max: max > v ? max : v,
  }), { min: arr[0], max: arr[0] });
}

또는 더 나은 런타임 *으로 :

function getMinMax(arr) {
  let min = arr[0];
  let max = arr[0];
  let i = arr.length;

  while (i--) {
    min = arr[i] < min ? arr[i] : min;
    max = arr[i] > max ? arr[i] : max;
  }
  return { min, max };
}

* 1,000,000 개 항목으로 테스트 :
참조 용으로, 첫 번째 기능 런타임 (내 컴퓨터)은 15.84ms 대 두 번째 기능은 4.32ms입니다.


13

이것은 귀하의 목적에 적합 할 수 있습니다.

Array.prototype.min = function(comparer) {

    if (this.length === 0) return null;
    if (this.length === 1) return this[0];

    comparer = (comparer || Math.min);

    var v = this[0];
    for (var i = 1; i < this.length; i++) {
        v = comparer(this[i], v);    
    }

    return v;
}

Array.prototype.max = function(comparer) {

    if (this.length === 0) return null;
    if (this.length === 1) return this[0];

    comparer = (comparer || Math.max);

    var v = this[0];
    for (var i = 1; i < this.length; i++) {
        v = comparer(this[i], v);    
    }

    return v;
}

숫자가 0보다 작은 경우를 대비하여 'this [0]'으로 v를 초기화해야합니다.
jasonmw

되어 comparer일부 특정 범위에 호출하는데? 왜냐하면 그것이 매번 참조 this[index]되는 것이기 때문입니다 undefined.
Roatin Marth

고정, 나는 항상 기능 수준 범위를 잊어 버렸습니다.
ChaosPandion

오 지금, 지금 @Ionut G. 스탠 그가 나에게했던 것처럼 (당신의 기본 비교하기 때문에, 같은 "잘못된 컨텍스트"인수 당신을 비판합니다 Math.xxx) 전역에서 실행됩니다 ...
Roatin Marth

사실 일 수도 있지만 새 함수 서명에는 비교해야 할 2 개의 개체가 필요하므로 범위가 필요하지 않습니다.
ChaosPandion 2009


12

축소 기능을 언급하지 않은 것에 놀랐습니다.

var arr = [1, 10, 5, 11, 2]

var b = arr.reduce(function(previous,current){ 
                      return previous > current ? previous:current
                   });

b => 11
arr => [1, 10, 5, 11, 2]

알아
두기

1
현재 버전의 Chromium에서는 이것을 사용할 수 없습니다.
PJSCopeland

9

큰 배열 (~ 10⁷ 요소)의 경우 Math.minMath.max procuces하면 RangeError node.js.에 (최대 호출 스택의 크기 초과)

큰 배열의 경우 빠르고 더러운 솔루션은 다음과 같습니다.

Array.prototype.min = function() {
    var r = this[0];
    this.forEach(function(v,i,a){if (v<r) r=v;});
    return r;
};

8

나는 같은 문제가 있었고 배열의 최소값과 최대 값을 얻어야했고 놀랍게도 배열에 대한 내장 함수가 없었습니다. 많은 내용을 읽은 후 "최고 3"솔루션을 직접 테스트하기로 결정했습니다.

  1. 이산 솔루션 : 현재 최대 및 / 또는 최소 값에 대해 어레이의 모든 요소를 ​​확인하는 FOR 루프.
  2. 적용 솔루션 : apply (null, array);를 사용하여 배열을 Math.max 및 / 또는 Math.min 내부 함수로 전송;
  3. REDUCE 솔루션 : reduce (function)를 사용하여 배열의 모든 요소에 대해 검사를 반복합니다.

테스트 코드는 다음과 같습니다.

function GetMaxDISCRETE(A)
{   var MaxX=A[0];

    for (var X=0;X<A.length;X++)
        if (MaxX<A[X])
            MaxX=A[X];

    return MaxX;
}

function GetMaxAPPLY(A)
{   return Math.max.apply(null,A);
}

function GetMaxREDUCE(A)
{   return A.reduce(function(p,c)
    {   return p>c?p:c;
    });
}

어레이 A는 100,000 개의 임의의 정수로 채워졌으며, 각 기능은 Windows Vista가 설치된 Intel Pentium 4 2.99GHz 데스크탑의 Mozilla Firefox 28.0에서 10,000 번 실행되었습니다. 시간은 초 단위이며 performance.now () 함수에 의해 검색됩니다. 결과는 다음과 같으며 3 개의 소수 자릿수와 표준 편차가 있습니다.

  1. 이산 솔루션 : 평균 = 0.161s, sd = 0.078
  2. 적용 솔루션 : 평균 = 3.571s, sd = 0.487
  3. REDUCE 솔루션 : 평균 = 0.350s, sd = 0.044

REDUCE 솔루션은 개별 솔루션보다 117 % 느 렸습니다. APPLY 솔루션은 개별 솔루션보다 2,118 % 느리게 나빴습니다. 또한 Peter가 관찰 한 것처럼 큰 배열 (약 1,000,000 개 이상의 요소)에서는 작동하지 않습니다.

또한 테스트를 완료하기 위해이 확장 된 이산 코드를 테스트했습니다.

var MaxX=A[0],MinX=A[0];

for (var X=0;X<A.length;X++)
{   if (MaxX<A[X])
        MaxX=A[X];
    if (MinX>A[X])
        MinX=A[X];
}

타이밍 : 평균 = 0.218s, sd = 0.094

따라서 단순 이산 솔루션보다 35 % 느리지 만 한 번에 최대 값과 최소값을 모두 검색합니다 (다른 솔루션은 검색하는 데 최소 두 배가 소요됨). 일단 OP가 두 값을 모두 필요로한다면, 이산 솔루션이 최선의 선택이 될 것입니다 (하나는 최대 값을 계산하기위한 함수와 최소값을 계산하기위한 함수 중 하나는 REDUCE 솔루션을 능가합니다).


8

프로젝트의 어느 곳에서나 다음 기능을 사용할 수 있습니다.

function getMin(array){
    return Math.min.apply(Math,array);
}

function getMax(array){
    return Math.max.apply(Math,array);
}

그런 다음 배열을 전달하는 함수를 호출 할 수 있습니다.

var myArray = [1,2,3,4,5,6,7];
var maximo = getMax(myArray); //return the highest number

8

다음 코드는 저에게 효과적입니다.

var valueList = [10,4,17,9,3];
var maxValue = valueList.reduce(function(a, b) { return Math.max(a, b); });
var minValue = valueList.reduce(function(a, b) { return Math.min(a, b); });

7

이동하면서 추적하면서 반복합니다.

var min = null;
var max = null;
for (var i = 0, len = arr.length; i < len; ++i)
{
    var elem = arr[i];
    if (min === null || min > elem) min = elem;
    if (max === null || max < elem) max = elem;
}
alert( "min = " + min + ", max = " + max );

배열에 요소가없는 경우 min / max는 null로 유지됩니다. 배열에 요소가있는 경우 한 번에 min과 max를 설정합니다.

range위 의 방법을 사용하여 Array를 확장 하여 재사용 성을 높이고 가독성을 향상시킬 수 있습니다. http://jsfiddle.net/9C9fU/ 에서 작동하는 바이올린을 참조하십시오.

Array.prototype.range = function() {

    var min = null,
        max = null,
        i, len;

    for (i = 0, len = this.length; i < len; ++i)
    {
        var elem = this[i];
        if (min === null || min > elem) min = elem;
        if (max === null || max < elem) max = elem;
    }

    return { min: min, max: max }
};

로 사용

var arr = [3, 9, 22, -7, 44, 18, 7, 9, 15];

var range = arr.range();

console.log(range.min);
console.log(range.max);

@JordanDillonChapian 동의하지만, range내 대답에 대한 업데이트로 완료 한 것처럼 IMO와 동시에 최소 및 최대를 모두 얻는 가장 좋은 방법이 될 수 있는 기능으로 이것을 확장하는 것은 사소한 일입니다.
tvanfosson

6

간단하고 이해하기 쉬운 솔루션을 공유한다고 생각했습니다.

최소 :

var arr = [3, 4, 12, 1, 0, 5];
var min = arr[0];
for (var k = 1; k < arr.length; k++) {
  if (arr[k] < min) {
    min = arr[k];
  }
}
console.log("Min is: " + min);

그리고 최대 :

var arr = [3, 4, 12, 1, 0, 5];
var max = arr[0];
for (var k = 1; k < arr.length; k++) {
  if (arr[k] > max) {
    max = arr[k];
  }
}
console.log("Max is: " + max);



감사. 나는 대답을 바꿨다.
Ionut Necula

반복이 여전히 잘못되었습니다 (존재하지 않는 속성에 액세스).
Bergi

무엇이 잘못되었는지, 나는 아무것도 잘못 보지 않습니다. 예를 들어 주시겠습니까?
Ionut Necula

1
이에 따라 수정되었습니다. 잘 이해했으면 좋겠습니다.
Ionut Necula

6

수학 함수 max와 min을 사용하는 것 외에도 사용할 또 다른 함수는 sort ()의 내장 함수입니다.

const nums = [12, 67, 58, 30].sort((x, y) => 
x -  y)
let max = nums[0]
let min = nums[nums.length -1]

5

정말 간단한 것입니다.

var arr = [10,20,30,40];
arr.max = function() { return  Math.max.apply(Math, this); }; //attach max funct
arr.min = function() { return  Math.min.apply(Math, this); }; //attach min funct

alert("min: " + arr.min() + " max: " + arr.max());

5

다음은 객체 배열에서 최대 값을 얻는 한 가지 방법입니다. 슬라이스를 사용하여 복사본을 만든 다음 복사본을 내림차순으로 정렬하고 첫 번째 항목을 가져옵니다.

var myArray = [
    {"ID": 1, "Cost": 200},
    {"ID": 2, "Cost": 1000},
    {"ID": 3, "Cost": 50},
    {"ID": 4, "Cost": 500}
]

maxsort = myArray.slice(0).sort(function(a, b) { return b.ID - a.ID })[0].ID; 

5

Math.max()또는 사용Math.min()

Math.max(10, 20);   //  20
Math.min(-10, -20); // -20

다음 함수는 Function.prototype.apply()숫자 형 배열에서 최대 요소를 찾는 데 사용 합니다. getMaxOfArray([1, 2, 3])와 동일 Math.max(1, 2, 3)하지만 getMaxOfArray()어떤 크기의 프로그래밍 방식으로 구성된 배열에 사용할 수 있습니다 .

function getMaxOfArray(numArray) {
  return Math.max.apply(null, numArray);
}

또는 새로운 스프레드 연산자를 사용하면 최대 배열을 얻는 것이 훨씬 쉬워집니다.

var arr = [1, 2, 3];
var max = Math.max(...arr); // 3
var min = Math.min(...arr); // 1

4

Protoype를 사용하는 경우 ChaosPandion의 솔루션이 작동합니다. 그렇지 않은 경우 다음을 고려하십시오.

Array.max = function( array ){
    return Math.max.apply( Math, array );
};

Array.min = function( array ){
    return Math.min.apply( Math, array );
};

위의 값은 배열 값이 정수가 아닌 경우 NaN을 반환하므로이를 피하기 위해 일부 기능을 빌드해야합니다. 그렇지 않으면 이것이 작동합니다.


jeerose, Roatin Marth에만 (null, this)있을 때 왜 (Math, this) agruments로 가지고 있습니까?
HankH

@HankH : 내 답변에 대한 의견에서 귀하의 의견에 대한 나의 답변을보십시오.
Roatin Marth

1
"protoype를 사용하는 경우 ChaosPandion의 솔루션이 작동 함"의 의미를 이해하지 못합니다. Math객체를 컨텍스트로 사용한다는 점을 제외하면 솔루션은 어떻게 다릅니 까?
Ionuț G. Stan

죄송합니다. 프로토 타입을 확장하면 프로토 타입을 사용할 수 있습니다. 사과.
jay

jeerose 또는 ChaosPandion의 어느 것이 더 낫습니까?
HankH 2009

3

sugar.js 라이브러리를 사용하면 다음 과 같이 작성할 수 있습니다. 제안한대로 arr.min () arr.max () 를. 숫자가 아닌 배열에서 최소값과 최대 값을 얻을 수도 있습니다.

min (map, all = false) 배열에서 가장 낮은 값을 가진 요소를 반환합니다. map은 확인할 값을 매핑하는 함수이거나 바로 가기 역할을하는 문자열 일 수 있습니다. 모두 참이면 배열의 모든 최소값을 반환합니다.

max (map, all = false) 배열에서 가장 큰 값을 가진 요소를 반환합니다. map은 확인할 값을 매핑하는 함수이거나 바로 가기 역할을하는 문자열 일 수 있습니다. 모두 참이면 배열의 모든 최대 값을 반환합니다.

예 :

[1,2,3].min() == 1
['fee','fo','fum'].min('length') == "fo"
['fee','fo','fum'].min('length', true) == ["fo"]
['fee','fo','fum'].min(function(n) { return n.length; }); == "fo"
[{a:3,a:2}].min(function(n) { return n['a']; }) == {"a":2}
['fee','fo','fum'].max('length', true) == ["fee","fum"]

Lo-Dash 와 같은 라이브러리 underscore.js도 유사한 강력한 최소 및 최대 기능을 제공합니다.

Lo-Dash의 예 :

_.max([4, 2, 8, 6]) == 8
var characters = [
  { 'name': 'barney', 'age': 36 },
  { 'name': 'fred',   'age': 40 }
];
_.max(characters, function(chr) { return chr.age; }) == { 'name': 'fred', 'age': 40 }

3
let arr = [2,5,3,5,6,7,1];

let max = Math.max(...arr); // 7
let min = Math.min(...arr); // 1

2
이 솔루션은 이미이 질문에 대한 다른 여러 답변자가 제공했습니다. 당신의 대답은 무엇을 추가합니까?
Nick

3

시험

let max= a=> a.reduce((m,x)=> m>x ? m:x);
let min= a=> a.reduce((m,x)=> m<x ? m:x);

Math.min / max (+ apply)의 경우 오류가 발생합니다.

최대 통화 스택 크기를 초과했습니다 (Chrome 74.0.3729.131)

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.