[JavaScript | 프로그래머스] 추억 점수

고은비·2023년 5월 11일
0

Algorithm

목록 보기
9/9
post-thumbnail

💡 사진들을 보며 추억에 젖어 있던 루는 사진별로 추억 점수를 매길려고 합니다. 사진 속에 나오는 인물의 그리움 점수를 모두 합산한 값이 해당 사진의 추억 점수가 됩니다. 예를 들어 사진 속 인물의 이름이 ["may", "kein", "kain"]이고 각 인물의 그리움 점수가 [5점, 10점, 1점]일 때 해당 사진의 추억 점수는 16(5 + 10 + 1)점이 됩니다. 다른 사진 속 인물의 이름이 ["kali", "mari", "don", "tony"]이고 ["kali", "mari", "don"]의 그리움 점수가 각각 [11점, 1점, 55점]]이고, "tony"는 그리움 점수가 없을 때, 이 사진의 추억 점수는 3명의 그리움 점수를 합한 67(11 + 1 + 55)점입니다.
그리워하는 사람의 이름을 담은 문자열 배열 name, 각 사람별 그리움 점수를 담은 정수 배열 yearning, 각 사진에 찍힌 인물의 이름을 담은 이차원 문자열 배열 photo가 매개변수로 주어질 때, 사진들의 추억 점수를 photo에 주어진 순서대로 배열에 담아 return하는 solution 함수를 완성해주세요.

입출력 예시

nameyearningphotoresult
["may", "kein", "kain", "radi"][5, 10, 1, 3][["may", "kein", "kain", "radi"],["may", "kein", "brin", "deny"], ["kon", "kain", "may", "coni"]][19, 15, 6]
["kali", "mari", "don"][11, 1, 55][["kali", "mari", "don"], ["pony", "tom", "teddy"], ["con", "mona", "don"]][67, 0, 55]
["may", "kein", "kain", "radi"][5, 10, 1, 3][["may"],["kein", "deny", "may"], ["kon", "coni"]][5, 15, 0]

Solution

function solution(name, yearning, photo) {
    let answer = new Array(photo.length).fill(0);
    for (let i = 0; i < photo.length; i++) {
        for (let j = 0; j < yearning.length; j++) {
            if (photo[i].includes(name[j])) {
                answer[i] += yearning[j]
            }
        }
    }
    return answer;
}

해결과정

  1. answer 배열을 photo 배열의 길이만큼 생성하고, 모든 요소를 0으로 초기화

  2. 이중 포문을 사용해서, photoyearning 배열을 반복하면서 photo 배열에 name요소가 포함되어 있는지 확인

  3. name 요소가 포함이 되어있다면 answer[i]에 해당 이름의 값(yearning[j])을 더해줌


다른 사람의 풀이

function solution(name, yearning, photo) {
    return photo.map((v)=> v.reduce((a, c)=> a += yearning[name.indexOf(c)] ?? 0, 0))
}

문제를 보자마자, reduce로 풀어야겠다! 라고 생각을 했지만 결국 돌고돌아 이중포문..🥲
아직 reduce 함수에 대해 개념이 확실하게 잡히지 않은 것 같아서 위 풀이를 보며 다시 공부를 해보았다.


💡 reduce()

reduce() 함수는 배열의 각 요소에 대해 주어진 콜백 함수를 실행하고, 최종적으로 하나의 값으로 축약하는 배열 메소드.

arr.reduce(callback[,initialValue])
  • callback : 배열의 각 요소에 대해 실행되는 함수로, 다음 매개변수를 받는다.
    - accumulator (누산기) : 콜백 함수에서 반환된 값 또는 이전 호출에서 반환된 값으로, 축적된 결과를 나타냄
    • currentValue (현재값) : 배열에서 처리 중인 현재 요소
    • currentIndex (현재 인덱스) : 배열에서 처리 중인 현재 요소의 인덱스
  • initialValue (옵션) : 콜백 함수의 첫번째 호출에서 사용되는 초기값으로, 생략할 수 있음. 초기값이 제공되지 않으면 배열의 첫번째 요소가 사용됨

💡 ?? (null 병합 연산자)

null 병합 연산자를 ?? 를 사용하면 짧은 문법으로 여러 피연산자 중 그 값이 확정되어 있는 변수를 찾을 수 있다.
다르게 말해, null 또는 undefined 인 값을 대체하기 위해서 사용된다.

a ?? b
- a가 null도 아니고 undefined도 아니면 a
- 그 외의 경우는 b (null 또는 undefined)

위 풀이에서 ?? 를 사용한 예시를 들어보면, name 배열에서 c의 indexOf를 찾을 수 없다면 -1를 반환한다. 이렇게 되면 yearning[-1] 은 NaN을 반환하게 되는데, ?? 연산자를 사용하여 기본값으로 '0'을 설정해줌으로써 예외 상황을 처리해줄 수 있다.

yearning[name.indexOf(c)] ?? 0

'??' 와 '||' 의 차이

nullish 병합 연산자는 OR 연산자 || 와 상당히 유사해 보인다. 실제로 위 알고리즘 문제에서는 ??를 ||로 바꿔도 그 결과는 동일하다.
하지만 두 연산자 사이에는 중요한 차이점이 있다.

  • | |는 첫번째 truthy 값을 반환한다.
  • ??는 첫번째 정의된(undefined) 값을 반환한다.
let height = 0;

alert(height || 100); // 100
alert(height ?? 100); // 0

첫번째로, height || 100 은 height에 0을 할당했지만, 0를 falsy한 값으로 취급하기 때문에 null이나 undefined를 할당한 것과 동일하게 처리한다. 따라서 height || 100의 평가 결과는 100이다.

반면 height ?? 100의 평가는 height가 정확하게 null이나 undefined일 경우에만 100이 된다. 예시에서는 height에 0 이라는 값을 할당했기 때문에 0이 출력된다.

이러한 특징 때문에 높이처럼 0이 할당될 수 있는 변수를 사용해 기능을 개발할 땐 || 보다 ??가 적합하다.

참고

0개의 댓글

관련 채용 정보