2차원 배열 데이터 key-value 객체로 만들기

곽형조 (KCena)·2020년 5월 9일
0

2차원 배열 데이터를 key-value 객체로 만들기

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),
    {}
  );
  1. 함수 몸체가 한줄의 구문일 경우 중괄호를 생략할 수 있고, 암묵적으로 return 된다.
  2. 쉼표 연산자는 각각의 피연산자를 왼쪽에서 오른쪽 순서로 평가하고, 마지막 연산자의 값을 반환한다. reduce 안에서 acc를 반환할 때 사용되는 부분이다. MDN 보다 설명을 잘 해주신 분의 블로그를 참고하자. <apricotsoul님의 velog> comma operator

참고 링크
[Javascript] map, reduce, filter를 유용하게 활용하는 15가지 방법
[poiemaweb] Arrow function

0개의 댓글