programmers의 위장 문제를 풀면서 2차원 배열 데이터를 key-value 쌍을 갖는 객체로 만들고 싶었다. 추후에도 이런 풀이를 사용할 일이 있을거라 생각하여 블로그에 남겨 놓기로 했다.
아래의 test case 처럼 2차원 배열을 객체로 바꾸고자 한다.
test("arrayToObject", () => {
expect(
arrayToObject([
["상의", "흰 티"],
["하의", "반바지"],
["상의", "검은 티"],
["모자", "볼 캡"],
["모자", "비니"],
["상의", "회색 티"],
])
).toStrictEqual({
상의: ["흰 티", "검은 티", "회색 티"],
하의: ["반바지"],
모자: ["볼 캡", "비니"],
});
});
const arrayToObject = (array) => {
// array 에 대해 reduce 메서드를 적용한다.
return array.reduce((acc, row) => {
// reduce의 초기값은 빈 객체이고, row는 2차원 배열의 한 행을 말한다.
// 하나의 행은 [옷의 종류, 옷 이름] 을 갖고 있으므로, 구조 분해 할당을 통해 나눈다.
const [kind, clothe] = row;
// acc는 객체다. kind에 해당하는 key에 value로 배열을 넣는 것인데,
// acc[kind]에 이미 데이터가 존재하면 spread 연산자로 펼쳐 넣어주고
// 만약 없다면 빈 배열의 데이터를 펼쳐 넣어준다. 즉 아무것도 안넣는다.
// 그 다음 clothe 값을 배열에 담아 넣는다.
acc[kind] = [...(acc[kind] || []), clothe];
return acc;
}, {});
};
이렇게 하면 2차원 배열 데이터를 객체로 만들 수 있다. 위 코드를 좀 더 간단히 작성하면 아래와 같다.
const arrayToObject = (array) =>
array.reduce(
(acc, row) => ((acc[row[0]] = [...(acc[row[0]] || []), row[1]]), acc),
{}
);
참고 링크
[Javascript] map, reduce, filter를 유용하게 활용하는 15가지 방법
[poiemaweb] Arrow function