
Array 인스턴스의 map() 메서드는 순회 메서드입니다,
이 메서드는 주어진 callbackFn함수를 배열의 각각의 요소당 한번씩 호출하여 그 결과로 새로운 배열을 생성
const array1 = [1, 4, 9, 16];
// 각 요소마다 2를 곱해줌
const map1 = array1.map((x) => x * 2);
// Array형식으로 [2, 8, 18, 32]가 출력됨
console.log(map1);
Array인스턴스의 flatMap() 메서드는 배열의 각 요소에 주어진 콜백 함수를 적용한 다음 그 결과를 한단계씩 평탄화하여 형성된 새 배열을 반환
const arr1 = [1, 2, 1];
const result = arr1.flatMap((num) => (num === 2 ? [2, 2] : 1));
// Array형식으로 평탄화되어 [1, 2, 2, 1] 출력됨
console.log(result);
map()함수는 알고있었다....
간단한 예시와 함께 설명이 있지만 응용문제가 나오는 순간 멘탈이 무너진다.
const detail_products = [
{
product_id: 1,
name: "GeForce RTX 4090",
category: {
category_id: 23,
name: "Graphic Card",
},
option: [
{
option_id: 12,
name: "256GB",
additional_price: 0,
},
{
option_id: 13,
name: "512GB",
additional_price: 100000,
},
],
price: 400000,
},
{
product_id: 2,
name: "Nike Air Max 97",
category: {
category_id: 108,
name: "Shoes",
},
option: [
{
option_id: 201,
name: "Triple White",
additional_price: 20000,
},
{
option_id: 202,
name: "Triple Black",
additional_price: 40000,
},
],
price: 200000,
},
];
상품의 상세정보와 함께 상품의 추가 옵션과 그에따른 추가 가격이 명시되어있다.
각 상품별로 해당 옵션을 각각 붙여서 출력하기를 원했다.
그래서 짠 코드가 아래와 같다.
// 함수선언
function productList(products) {
// 함수의 결과를 배열값으로 넘겨주기위해 변수를 선언해서 함
// (사실 지속적으로 consloe.log()를 하기위해서 생성한 이유도 있음...)
const result = products.map(
// 객체 비구조화
({ product_id, name, category: { name: categoryName }, option, price }) =>
// 상품에 option의 갯수만큼 추가 후 map의 결과를 객체로 반환
option.map(({ name: optionName, additional_price }) => ({
product_id,
name,
category: categoryName,
option: { name: optionName, additional_price },
totalPrice: price + additional_price,
}))
);
return result;
}
해당문제는 복잡해 보이지만 이중for문이라고 생각해보니 접근이 조금 용이했었다
[
[
{
product_id: 1,
name: 'GeForce RTX 4090',
category: 'Graphic Card',
option: [Object],
totalPrice: 400000
},
{
product_id: 1,
name: 'GeForce RTX 4090',
category: 'Graphic Card',
option: [Object],
totalPrice: 500000
}
],
[
{
product_id: 2,
name: 'Nike Air Max 97',
category: 'Shoes',
option: [Object],
totalPrice: 220000
},
{
product_id: 2,
name: 'Nike Air Max 97',
category: 'Shoes',
option: [Object],
totalPrice: 240000
}
],
]
option: [Object]에 [Object]부분이 있다는 것이다!!
이를 어떻게 해결할까?
option: '{"name":"256GB","additional_price":0}',
출력은 된다 그리고 option의 타입도 object이다.
하지만 출력결과 string이 아닌 객체로 깔끔하게 나오게 하고싶었다.
option: JSON.parse(JSON.stringify({ name: optionName, additional_price }))
option부분만 위 코드를 수정했다. 정상적으로 출력이 된다
하지만 코드가 너무 복잡해서 가독성이 떨어진다.
// 함수선언
function productList(products) {
// products.map()에서 products.flatMap()으로 바꿨다
const result = products.flatMap(
({ product_id, name, category: { name: categoryName }, option, price }) =>
option.map(({ name: optionName, additional_price }) => ({
product_id,
name,
category: categoryName,
option: { name: optionName, additional_price },
totalPrice: price + additional_price,
}))
);
return result;
}
[
{
product_id: 1,
name: 'GeForce RTX 4090',
category: 'Graphic Card',
option: { name: '256GB', additional_price: 0 },
totalPrice: 400000,
optype: 'object'
},
{
product_id: 1,
name: 'GeForce RTX 4090',
category: 'Graphic Card',
option: { name: '512GB', additional_price: 100000 },
totalPrice: 500000,
optype: 'object'
},
{
product_id: 2,
name: 'Nike Air Max 97',
category: 'Shoes',
option: { name: 'Triple White', additional_price: 20000 },
totalPrice: 220000,
optype: 'object'
},
{
product_id: 2,
name: 'Nike Air Max 97',
category: 'Shoes',
option: { name: 'Triple Black', additional_price: 40000 },
totalPrice: 240000,
optype: 'object'
},
]
하핫!! 원하던 결과가 나왔다!
map()만 사용하면 결과가 중첩된 배열이 된다.
중첩 배열 상태에서 출력하면 객체들이 [Object]로 보일수 있음.
flatMap()을 사용하면 중첩된 배열을 평탄화하므로, 내부 객체들이 배열 최상위에 위치(한마디로 객체를 풀어준다는 의미)
따라서 데이터가 중첩된 형태로 변환되는 상황에서는 flatMap()이 더 적합함.