데이터 구조에서 원하는 데이터만 뽑아서 배열을 만들고 싶었다.
처음에는 map이용하여 배열을 만들었지만 뽑아내야하는 데이터의 배열의 갯수가 2개 이상이 되어서 reduce 함수를 이용하여 한꺼번에 처리하였다.
함수를 실행하고 하나의 결과값을 얻는다. 그리고 두개의 인자와 옵셔널 2개를 갖는다.
acc
accumulator - 출력되는 값
cur
current - 현재 요소
index
index(Optional) - 현재 요소의 인덱스
array
array(Optional) - 호출한 배열
data: {
segments: {
name: string;
contents: {
name: string;
item: string[];
}[];
}[];
};
이런 구조의 데이터가 있다고 하면 내가 뽑아내고 싶은 배열은 data.segments[].name
data.segments[].contents[].name
data.segments[].contents[].item[]
이렇게 세개이다.
이 세개를 새로운 배열로 만들고 싶어서 처음에는 data.segments[].name
name 필드를 map으로 뽑아냈다.
const dataName = data.segments.map(({ name }) => name);
dataName을 호출해 보면 name만 배열로 추출할 수 있다.
근데 이렇게 const를 사용하여 map으로 다 추출하기 보단 구조 분해 할당으로 reduce함수로 리팩토링 했다.
const { dataName, contentName, contentItem } = data.segments.reduce<{
dataName: string[];
contentName: string[];
contentItem: string[][];
}>(
(acc, cur) => {
acc.dataName = [...acc.dataName, cur.name];
acc.contentName = [...acc.contentName, ...cur.contents.map((content) => content.name)];
acc.contentItem = [...acc.contentItem, ...cur.contents.map((content) => content.item)];
return acc;
},
{ dataName: [], contentName: [], contentItem: [] },
);
...연산자
를 사용하고 싶지 않으면 push()
메서드를 이용하면 된다.
그리고 데이터를 가져올 때 타입스크립트로 작성이 되어있으면 굳이 ...cur.contents를 map으로 돌리지 않아도 타입을 명시할 때 해당하는 interface를 가져오면 된다.
이렇게 공부하고 잘 끝낸 프로젝트 끝!