자바스크립트 every() 함수: 배열 검사 한번에 하기
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/every
Array.prototype.every() - JavaScript | MDN
Array 인스턴스의 every() 메서드는 배열의 모든 요소가 제공된 함수로 구현된 테스트를 통과하는지 테스트합니다. 이 메서드는 불리언 값을 반환합니다.
developer.mozilla.org
Array 인스턴스의 every() 메서드는 배열의 모든 요소가 제공된 함수로 구현된 테스트를 통과하는지 테스트합니다. 이 메서드는 불리언 값을 반환합니다.
#시도해보기
JavaScript Demo: Array.every()
const isBelowThreshold = (currentValue) => currentValue < 40;
const array1 = [1, 30, 39, 29, 10, 13];
console.log(array1.every(isBelowThreshold));
// Expected output: true
--> 결과 : true 가 나온다.
JS
every(callbackFn)
every(callbackFn, thisArg)
매개변수
배열의 각 요소에 대해 실행할 함수입니다. 요소가 테스트를 통과하면 참 값을 반환하고, 그렇지 않으면 거짓 값을 반환해야 합니다. 함수는 다음 인자를 사용하여 호출됩니다.
배열에서 처리되는 현재 요소.
처리되는 현재 요소의 인덱스.
every()를 호출한 배열.
thisArg : Optional
callbackFn을 실행할 때 this로 사용하는 값. 순회 메서드를 참조하세요.
반환 값
callbackFn이 모든 배열 요소에 대해 참 값을 반환하면 true입니다. 그렇지 않으면 false입니다.
설명
every() 메서드는 순회 메서드입니다. 배열의 각 요소에 대해 제공된 callbackFn 함수를 한 번씩 호출하고, callbackFn이 거짓 값을 반환할 때까지 호출을 반복합니다. 거짓 요소가 발견되면 every()는 즉시 false를 반환하고 배열 순회를 중지합니다. 그렇지 않고 callbackFn이 모든 요소에 대해 참 값을 반환하면, every()는 true를 반환합니다.
예제
모든 배열 요소의 크기 테스트
다음 예제는 배열의 모든 요소가 9보다 더 큰지 테스트합니다.
JS
function isBigEnough(element, index, array) {
return element >= 10;
}
[12, 5, 8, 130, 44].every(isBigEnough); // false
[12, 54, 18, 130, 44].every(isBigEnough); // true
한 배열이 다른 배열의 부분 집합인지 확인
다음 예제는 배열의 모든 요소가 다른 배열에 존재하는지 테스트합니다.
JS
const isSubset = (array1, array2) =>
array2.every((element) => array1.includes(element));
console.log(isSubset([1, 2, 3, 4, 5, 6, 7], [5, 7, 6])); // true
console.log(isSubset([1, 2, 3, 4, 5, 6, 7], [5, 8, 7])); // false
첫번째 화살표 함수 : isSubset 함수를 정의
const isSubset = (array1, array2) =>
이 부분은 isSubset이라는 이름의 함수를 정의합니다. 이 함수는 두 개의 매개변수 array1과 array2를 받습니다.
- const isSubset = (array1, array2) =>는 array1과 array2를 인자로 받아서, 이들을 이용해 표현식의 결과를 반환하는 함수를 정의하는 부분입니다.
- 여기서 array1과 array2는 함수의 매개변수입니다.
두번째 화살표 함수 : every 메서드 내에서 각 요소를 검사하는 콜백 함수를 정의
array2.every((element) => array1.includes(element));
이 부분은 every 메서드에 전달된 콜백 함수입니다. 이 콜백 함수는 array2의 각 요소에 대해 실행됩니다.
- (element) => array1.includes(element)는 array2의 각 요소를 element로 받아들여 array1에 해당 element가 포함되어 있는지를 검사합니다.
- 이 화살표 함수는 element를 매개변수로 받아서, array1.includes(element)라는 표현식을 실행하고 그 결과를 반환합니다.
array2.every((element) => array1.includes(element))는 array2의 모든 요소에 대해 콜백 함수 (element) => array1.includes(element)를 실행합니다.
every 메서드는 array2의 각 요소가 array1에 포함되어 있는지 (array1.includes(element))를 확인합니다.
array1.includes(element)는 array1에 element가 있는지 확인하고, 있으면 true를, 없으면 false를 반환합니다.
every 메서드는 콜백 함수가 모든 요소에 대해 true를 반환할 경우 true를 반환하며, 그렇지 않으면 false를 반환합니다.
희소 배열에 every() 사용하기
every() 는 빈 슬롯에 콜백 함수를 실행하지 않습니다.
JS
console.log([1, , 3].every((x) => x !== undefined)); // true
console.log([2, , 2].every((x) => x === 2)); // true
---------------------------------------------------------------------------------------------------------------------------------------------
초기 배열에 영향주기(수정, 추가, 삭제)
다음 예제는 배열이 수정되었을 때 every 메서드의 동작을 테스트합니다.
JS
// ---------
// 항목 수정
// ---------
let arr = [1, 2, 3, 4];
arr.every((elem, index, arr) => {
arr[index + 1]--; // 현재 인덱스의 다음 요소를 감소시킵니다.
console.log(`[${arr}][${index}] -> ${elem}`); // 현재 배열 상태와 인덱스, 요소를 출력합니다.
return elem < 2; // 현재 요소가 2보다 작은지 확인합니다.
});
// 루프는 3번 순회하지만,
// 수정이 없었다면 2번만 순회했을 것입니다.
//
// 첫 번째 순회: [1,1,3,4][0] -> 1
// 두 번째 순회: [1,1,2,4][1] -> 1
// 세 번째 순회: [1,1,2,3][2] -> 2
// ---------
// 항목 추가
// ---------
arr = [1, 2, 3];
arr.every((elem, index, arr) => {
arr.push("new");
console.log(`[${arr}][${index}] -> ${elem}`);
return elem < 4;
});
// 새로운 요소가 추가된 후에도 3번만 순회합니다.
//
// 첫 번째 순회: [1, 2, 3, new][0] -> 1
// 두 번째 순회: [1, 2, 3, new, new][1] -> 2
// 세 번째 순회: [1, 2, 3, new, new, new][2] -> 3
// ---------
// 항목 삭제
// ---------
arr = [1, 2, 3, 4];
arr.every((elem, index, arr) => {
arr.pop();
console.log(`[${arr}][${index}] -> ${elem}`);
return elem < 4;
});
// 기존 요소가 `pop()` 되어 2번만 순회합니다.
//
// 첫 번째 순회: [1,2,3][0] -> 1
// 두 번째 순회: [1,2][1] -> 2
// 항목 수정
// ---------
let arr = [1, 2, 3, 4];
arr.every((elem, index, arr) => {
arr[index + 1]--; // 현재 인덱스의 다음 요소를 감소시킵니다.
console.log(`[${arr}][${index}] -> ${elem}`); // 현재 배열 상태와 인덱스, 요소를 출력합니다.
return elem < 2; // 현재 요소가 2보다 작은지 확인합니다.
});
세부 실행 결과
각 단계에서 배열의 상태와 every의 반환 값을 살펴보겠습니다.
- 첫 번째 요소 (index 0):
- 현재 배열 상태: [1, 2, 3, 4]
- elem: 1
- index: 0
- arr[index + 1]-- 수행 후 배열: [1, 1, 3, 4]
- 출력: [1,1,3,4][0] -> 1
- 반환 값: 1 < 2는 true
- 두 번째 요소 (index 1):
- 현재 배열 상태: [1, 1, 3, 4]
- elem: 1
- index: 1
- arr[index + 1]-- 수행 후 배열: [1, 1, 2, 4]
- 출력: [1,1,2,4][1] -> 1
- 반환 값: 1 < 2는 true
- 세 번째 요소 (index 2):
- 현재 배열 상태: [1, 1, 2, 4]
- elem: 2
- index: 2
- arr[index + 1]-- 수행 후 배열: [1, 1, 2, 3]
- 출력: [1,1,2,3][2] -> 2
- 반환 값: 2 < 2는 false
네 번째 요소는 검사되지 않습니다. every 메서드는 false를 반환하므로 배열 순회를 중단합니다.
따라서, 최종 결과는 false입니다.
항목 추가
// ---------
arr = [1, 2, 3];
arr.every((elem, index, arr) => {
arr.push("new");
console.log(`[${arr}][${index}] -> ${elem}`);
return elem < 4;
});
다음 코드는 배열 arr의 각 요소에 대해 검사하면서 각 요소가 4보다 작은지 확인하고, 배열의 끝에 "new" 항목을 추가하며 배열의 변화를 출력합니다:
코드 실행 설명
- 초기 설정:
- 배열 arr을 [1, 2, 3]으로 초기화합니다.
- 첫 번째 요소 (index 0):
- every 메서드가 배열의 첫 번째 요소 1을 처리합니다.
- arr.push("new")로 배열 끝에 "new"를 추가합니다. 배열 상태는 [1, 2, 3, "new"]가 됩니다.
- console.log로 현재 배열 상태와 인덱스, 요소를 출력합니다. 출력: "[1,2,3,new][0] -> 1".
- return elem < 4는 1 < 4이므로 true를 반환합니다.
-
- every 메서드가 배열의 두 번째 요소 2를 처리합니다.
- arr.push("new")로 배열 끝에 "new"를 추가합니다. 배열 상태는 [1, 2, 3, "new", "new"]가 됩니다.
- console.log로 현재 배열 상태와 인덱스, 요소를 출력합니다. 출력: "[1,2,3,new,new][1] -> 2".
- return elem < 4는 2 < 4이므로 true를 반환합니다.
- 첫 번째 요소 (index 1):
- 세 번째 요소 (index 2):
- every 메서드가 배열의 세 번째 요소 3을 처리합니다.
- arr.push("new")로 배열 끝에 "new"를 추가합니다. 배열 상태는 [1, 2, 3, "new", "new", "new"]가 됩니다.
- console.log로 현재 배열 상태와 인덱스, 요소를 출력합니다. 출력: "[1,2,3,new,new,new][2] -> 3".
- return elem < 4는 3 < 4이므로 true를 반환합니다.
- 네 번째 요소 (index 3):
- every 메서드가 배열의 네 번째 요소 "new"를 처리합니다.
- arr.push("new")로 배열 끝에 "new"를 추가합니다. 배열 상태는 [1, 2, 3, "new", "new", "new", "new"]가 됩니다.
- console.log로 현재 배열 상태와 인덱스, 요소를 출력합니다. 출력: "[1,2,3,new,new,new,new][3] -> new".
- return elem < 4는 "new" < 4가 아니므로 false를 반환합니다.
every 메서드는 false를 반환하는 요소를 만나면 즉시 순회를 중단합니다. 따라서, 네 번째 요소에서 중단되어 더 이상 진행되지 않습니다.
최종 결과
- 배열 arr의 상태는 [1, 2, 3, "new", "new", "new", "new"]입니다.
- every 메서드는 false를 반환합니다.
// 항목 삭제
// ---------
arr = [1, 2, 3, 4];
arr.every((elem, index, arr) => {
arr.pop();
console.log(`[${arr}][${index}] -> ${elem}`);
return elem < 4;
});
다음 코드는 배열 arr의 각 요소에 대해 검사하면서 각 요소가 4보다 작은지 확인하고, 배열의 끝에서 요소를 제거하며 배열의 변화를 출력합니다:
코드 실행 설명
- 초기 설정:
- 배열 arr을 [1, 2, 3, 4]로 초기화합니다.
- 첫번째 요소(index 0):
- every 메서드가 배열의 첫 번째 요소 1을 처리합니다.
- arr.pop()로 배열 끝의 요소를 제거합니다. 배열 상태는 [1, 2, 3]가 됩니다.
- console.log로 현재 배열 상태와 인덱스, 요소를 출력합니다. 출력: "[1,2,3][0] -> 1".
- return elem < 4는 1 < 4이므로 true를 반환합니다.
- 두 번째 요소 (index 1):
- every 메서드가 배열의 두 번째 요소 2를 처리합니다.
- arr.pop()로 배열 끝의 요소를 제거합니다. 배열 상태는 [1, 2]가 됩니다.
- console.log로 현재 배열 상태와 인덱스, 요소를 출력합니다. 출력: "[1,2][1] -> 2".
- return elem < 4는 2 < 4이므로 true를 반환합니다.
- 세 번째 요소 (index 2):
- every 메서드가 배열의 세 번째 요소 3을 처리합니다.
- arr.pop()로 배열 끝의 요소를 제거합니다. 배열 상태는 [1]가 됩니다.
- console.log로 현재 배열 상태와 인덱스, 요소를 출력합니다. 출력: "[1][2] -> 3".
- return elem < 4는 3 < 4이므로 true를 반환합니다.
- 네 번째 요소는 없음 (index 3):
- 배열의 네 번째 요소는 더 이상 존재하지 않으므로 every 메서드는 더 이상 순회를 진행하지 않습니다.
최종 결과
- 배열 arr의 상태는 [1]입니다.
- every 메서드는 true를 반환합니다, 왜냐하면 return elem < 4 조건이 검사된 모든 요소에 대해 참이었기 때문입니다.
한 줄 한 줄 설명:
- arr를 [1, 2, 3, 4]로 초기화합니다.
- arr.every 메서드를 호출하여 배열의 각 요소에 대해 콜백 함수를 실행합니다.
- 첫 번째 요소 (index 0):
- arr.pop()로 배열의 끝에서 요소를 제거합니다. 결과: [1, 2, 3].
- 현재 배열 상태와 인덱스, 요소를 출력합니다: [1,2,3][0] -> 1.
- return elem < 4는 1 < 4이므로 true를 반환합니다.
- 두 번째 요소 (index 1):
- arr.pop()로 배열의 끝에서 요소를 제거합니다. 결과: [1, 2].
- 현재 배열 상태와 인덱스, 요소를 출력합니다: [1,2][1] -> 2.
- return elem < 4는 2 < 4이므로 true를 반환합니다.
- 세 번째 요소 (index 2):
- arr.pop()로 배열의 끝에서 요소를 제거합니다. 결과: [1].
- 현재 배열 상태와 인덱스, 요소를 출력합니다: [1][2] -> 3.
- return elem < 4는 3 < 4이므로 true를 반환합니다.
- 더 이상 요소가 없으므로 순회가 종료됩니다.
결과적으로 every 메서드는 true를 반환하고, 배열의 최종 상태는 [1]이 됩니다.
배열이 아닌 객체에서 every() 호출하기
every() 메서드는 this의 length 속성을 읽은 다음, length보다 작은 음수가 아닌 정수 키의 각 속성에 모두 접근하거나 callbackFn이 false를 반환할 때까지 접근합니다.
JS
const arrayLike = {
length: 3,
0: "a",
1: "b",
2: "c",
3: 345, // length가 3이므로 every()에 의해 무시됩니다.
};
console.log(
Array.prototype.every.call(arrayLike, (x) => typeof x === "string"),
); // true