every()
메서드는 배열 안의 모든 요소가 주어진 판별 함수를 통과하는지 테스트합니다. Boolean 값을 반환합니다.
[12, 5, 8, 130, 44].every(elem => elem >= 10); // false
[12, 54, 18, 130, 44].every(elem => elem >= 10); // true
some()
메서드는 배열 안의 어떤 요소라도 주어진 판별 함수를 통과하는지 테스트합니다. Boolean 값을 반환합니다. 빈 배열에서 호출하면 무조건 false를 반환합니다.
[2, 5, 8, 1, 4].some(elem => elem > 10); // false
[12, 5, 8, 1, 4].some(elem => elem > 10); // true
fill()
메서드는 배열의 시작 인덱스부터 끝 인덱스의 이전까지 정적인 값 하나로 채웁니다.
arr.fill(value, start, end)
fill은 일반 함수이며, this 값이 배열 객체일 필요는 없습니다.
fill 메서드는 변경자 메서드로, 복사본이 아니라 this 객체를 변형해 반환합니다.
value에 객체를 받을 경우 그 참조만 복사해서 배열을 채웁니다.
[1, 2, 3].fill(4); // [4, 4, 4]
[1, 2, 3].fill(4, 1); // [1, 4, 4]
[1, 2, 3].fill(4, 1, 2); // [1, 4, 3]
[1, 2, 3].fill(4, 1, 1); // [1, 2, 3]
[1, 2, 3].fill(4, 3, 3); // [1, 2, 3]
[1, 2, 3].fill(4, -3, -2); // [4, 2, 3]
[1, 2, 3].fill(4, NaN, NaN); // [1, 2, 3]
[1, 2, 3].fill(4, 3, 5); // [1, 2, 3]
Array(3).fill(4); // [4, 4, 4]
[].fill.call({ length: 3 }, 4); // {0: 4, 1: 4, 2: 4, length: 3}
// Objects by reference.
var arr = Array(3).fill({}); // [{}, {}, {}]
arr[0].hi = "hi"; // [{ hi: "hi" }, { hi: "hi" }, { hi: "hi" }]
find()
메서드는 주어진 판별 함수를 만족하는 첫 번째 요소의 값을 반환합니다. 그런 요소가 없다면 undefined를 반환합니다.
const inventory = [
{name: 'apples', quantity: 2},
{name: 'bananas', quantity: 0},
{name: 'cherries', quantity: 5}
];
const result = inventory.find(fruit => fruit.name === 'cherries');
console.log(result) // { name: 'cherries', quantity: 5 }
flat()
메서드는 모든 하위 배열 요소를 지정한 깊이까지 재귀적으로 이어붙인 새로운 배열을 생성합니다.(지정한 깊이까지 배열 평탄화)
const arr1 = [1, 2, [3, 4]];
arr1.flat();
// [1, 2, 3, 4]
const arr2 = [1, 2, [3, 4, [5, 6]]];
arr2.flat();
// [1, 2, 3, 4, [5, 6]]
const arr3 = [1, 2, [3, 4, [5, 6]]];
arr3.flat(2);
// [1, 2, 3, 4, 5, 6]
const arr4 = [1, 2, [3, 4, [5, 6, [7, 8, [9, 10]]]]];
arr4.flat(Infinity);
// [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
배열의 구멍 제거에도 활용 가능
const arr5 = [1, 2, , 4, 5];
arr5.flat();
// [1, 2, 4, 5]
flatMap()
메서드는 먼저 매핑함수를 사용해 각 엘리먼트에 대해 map 수행 후, 결과를 새로운 배열로 평탄화합니다. 이는 깊이 1의 flat 이 뒤따르는 map 과 동일하지만, flatMap 은 아주 유용하며 둘을 하나의 메소드로 병합할 때 조금 더 효율적입니다. (map
한 후에 flat
하는 개념)
let arr1 = [1, 2, 3, 4];
arr1.map(x => [x * 2]);
// [[2], [4], [6], [8]]
arr1.flatMap(x => [x * 2]);
// [2, 4, 6, 8]
// 한 레벨만 평탄화됨
arr1.flatMap(x => [[x * 2]]);
// [[2], [4], [6], [8]]
위 예시보다 아래 문자열 예시가 알고리즘 문제에서 응용하기 좋아보임.
let arr1 = ["it's Sunny in", "", "California"];
arr1.map(x=>x.split(" "));
// [["it's","Sunny","in"],[""],["California"]]
arr1.flatMap(x => x.split(" "));
// ["it's","Sunny","in","California"]
reduce()
메서드는 배열의 각 요소에 대해 주어진 리듀서(reducer) 함수를 실행하고, 하나의 결과값을 반환합니다.
배열.reduce((누적값, 현잿값, 인덱스, 요소) => { return 결과 }, 초깃값);
리듀서 함수는 네 개의 인자를 가집니다.
리듀서 함수의 반환 값은 누산기에 할당되고, 누산기는 순회 중 유지되므로 결국 최종 결과는 하나의 값이 됩니다.
덧셈 예시
//초기값을 0으로 설정할 경우
result = oneTwoThree.reduce((acc, cur, i) => {
console.log(acc, cur, i);
return acc + cur;
}, 0);
// 0 1 0
// 1 2 1
// 3 3 2
result; // 6
//초기값을 설정하지 않을 경우 = 바로 첫 요소가 초기값이 된다.
result = oneTwoThree.reduce((acc, cur, i) => {
console.log(acc, cur, i);
return acc + cur;
});
// 1 2 1
// 3 3 2
result; // 6
reduceRight도 있는데, 순서만 반대로!
result = oneTwoThree.reduceRight((acc, cur, i) => {
console.log(acc, cur, i);
return acc + cur;
}, 0);
// 0 3 2
// 3 2 1
// 5 1 0
result; // 6
덧셈 예시 이외의 활용
//map과 유사한 활용이 가능하다.
result = oneTwoThree.reduce((acc, cur) => {
acc.push(cur % 2 ? "홀수" : "짝수");
return acc;
}, []);
result; // ['홀수', '짝수', '홀수']
//filter와 유사한 활용이 가능하다.
result = oneTwoThree.reduce((acc, cur) => {
if (cur % 2) acc.push(cur);
return acc;
}, []);
result; // [1, 3]
//심지어 비동기 프로그래밍도 가능하다.
const promiseFactory = (time) => {
return new Promise((resolve, reject) => {
console.log(time);
setTimeout(resolve, time);
});
};
[1000, 2000, 3000, 4000].reduce((acc, cur) => {
return acc.then(() => promiseFactory(cur));
}, Promise.resolve());
// 바로 1000
// 1초 후 2000
// 2초 후 3000
// 3초 후 4000
reduce에 대한 감상은...
누적값을 갖고다니는 forEach
같은 느낌?