코딩테스트/프로그래머스

[JS] 의상 (+ 배열 `reduce` 메소드)

joycie416 2024. 9. 12. 23:46

 

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

문제 이해

이 문제에서 키 포인트는 이름이 같은 의상은 없다는 것이다. 결국 가지고 있는 의상의 종류 마다의 개수를 세서 다 곱한 후에 아무 것도 착용하지 않은 경우를 빼주면 된다.

 

방법 1

아래에 나올 방법 2와 따지고 보면 같은 방법이지만 아직 `reduce` 메소드를 자유롭게 다룰 수 있는 수준은 아니라서 기록해본다.

 

먼저 말했듯이 언급된 의상을 종류별로 카운트하기만 하면 된다.

 

  1. 늘 했듯이 빈 객체를 만들고 `undefined`가 아니면 +1, `undefined`이면 value가 1이 되도록 key-value 쌍을 추가한다.
  2. 그리고 해당 배열의 value만 모은 배열에 대해 `reduce` 메소드를 적용해 답을 구했다.
function solution(clothes) {
  const counts = {};
  for (const [_, type] of clothes) {
    if(counts[type]) {
      counts[type]++;
    } else {
      counts[type] = 1;
    }
  }

  return Object.values(counts).reduce((acc, cur) => acc*(cur+1), 1) - 1;
}

 

방법 2

`reduce` 메소드는 위에서 콜백 함수 내부에 `acc`라고 쓴 값의 초기값을 설정해줄 수 있다. 곱셈을 하기 위해서 위 코드는 초기값을 1로 두었다. 이처럼 초기값을 원하는 대로 설정할 수 있어 자유도가 높은 메소드라고 볼 수 있다.

 

초기값을 빈 배열로 두고 `clothes`에 대해 `reduce`를 적용해 for문에서 적은 것처럼 과정을 수행해주면 된다.

function solution(clothes) {
  return Object.values(clothes.reduce((obj, type)=> {
      obj[type[1]] = obj[type[1]] ? obj[type[1]] + 1 : 1;
      return obj;
  } , {})).reduce((a,b)=> a*(b+1), 1)-1;    
}

 

`type`은 `[의상 이름, 의상 종류]`로 구성된 배열이므로 1번째 인덱스만 사용해주면 된다.

 

자세히 뜯어보자. 첫 번째 `reduce`에 사용된 콜백 함수는 다음과 같다.

function (obj, type) {
  obj[type[1]] = obj[type[1]] ? obj[type[1]] + 1 : 1;
  return obj;
}

 

두 번째 `reduce`에서 사용된 콜백 함수는 다음과 같다.

function (a,b) {
  return a*(b+1);
}

 

따라서 배열이 생성되는 첫 번째 `reduce`의 결과에 따라 그 value들의 배열을 구하기 위해 `Object.values()`가 사용된 것이고, 그 배열에 두 번째 `reduce`를 적용해 착용할 수 있는 모든 경우의 수를 구한 것이다.

 

`reduce()` 메소드

위에 이야기 했듯이 `reduce`는 콜백 함수를 필요로 하며, 최대 네 개의 argument를 받을 수 있다. 콜백 함수의 parameter의 순서는 정해져 있어, 원하는 대로 그 순서를 바꿀 수 없다. 메소드의 두 번째 argument는 콜백 함수의 첫 번재 parameter의 초기값이다.

 

콜백 함수를 좀 더 살펴보자.

 

  • 첫 번째 인자 : 위에 언급했듯이 콜백함수의 결과값이 반복적으로 적용된다. 맨 처음에는 초기값을 특정한 경우 그 값이 주어진다.
  • 두 번째 인자 : 배열의 값들이 순차적으로 대입된다.
  • 세 번재 인자 : 두 번째 인자의 인덱스, 즉 현재 인덱스가 대입된다.
  • 네 번째 인자 : 배열 자체가 대입된다. 

 

지금까지는 세 번재, 네 번째 인자까지 사용한 적은 한 번 정도밖에 없지만, 언젠가 필요할 수 있으니 기억해둬도 좋을 것 같다.

 

만약 `reduce`의 두번째 argument가 주어지지 않으면, 배열의 0번째 값을 초기값으로 가지며, 1번째 값부터 콜백 함수를 적용한다.