JavaScript 배열의 최소 또는 최대 요소를 쉽게 얻을 수있는 방법은 무엇입니까?
유사 코드 예 :
let array = [100, 0, 50]
array.min() //=> 0
array.max() //=> 100
답변
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 );
답변
var max_of_array = Math.max.apply(Math, array);
자세한 내용은 http://aaroncrane.co.uk/2008/11/javascript_max_api/를 참조하십시오.
답변
큰 배열 (~ 10⁷ 요소)의 경우 Math.min
와 Math.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;
};
답변
답변
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 벤치 마크
JSBen 벤치 마크
JSBench.me 벤치 마크
벤치 마크 소스 코드
답변
사용에 대해 나처럼 편집증 경우 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
단지 통과하지 못할 a
와 b
그 기능에, 또한 i
우리는 우리가 전화를하지 않도록 할 수 있도록하고, 배열 자체에 대한 참조 max
뿐만 아니라 이들에.
답변
.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']