<문제 설명>
사진들을 보며 추억에 젖어 있던 루는 사진별로 추억 점수를 매길려고 합니다.
사진 속에 나오는 인물의 그리움 점수를 모두 합산한 값이 해당 사진의 추억 점수가 됩니다.
예를 들어 사진 속 인물의 이름이 ["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 함수를 완성해주세요.
<입출력>
name | yearning | photo | result |
["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] |
<문제 풀이 1>
function solution(name, yearning, photo) {
let answer = [];
for (let i = 0; i < photo.length; i++) {
let sum = 0;
photo[i].forEach((person) => {
sum += yearning[name.indexOf(person)]||0;
});
answer.push(sum);
}
return answer;
}
처음엔 배열 안에 배열이 있어서 map과 reduce를 떠올리긴 했는데,
해보다가 아직 익숙치 않아서 일단 푸는데 집중했다.
조금 더 일차원적인 방법으로 풀게 된다면, photo를 검사하면서 name의 인덱스와
yearning의 인덱스가 같기 때문에 name에 해당하는 yearning의 값을 더해줄텐데
이번에는 if로 조건을 걸기보다 아닐 경우 0을 더했다.
sum에 어떤 값을 더할텐데, 그 값은 yearning의 어떤 인덱스값이다.
그리고 그 인덱스값은 photo를 돌면서 보이는 값을 name에서 찾고,
name에 있으면 name의 위치에 있는 인덱스를 yearning에 대입해서 더하고,
name에 없으면 0을 더하는 것이다.
이제 처음에 생각했던 방법을 떠올려보자.
function solution(name, yearning, photo) {
let answer = photo.map((v)=>
v.reduce((a, c)=>
a += yearning[name.indexOf(c)] || 0,0))
return answer;
}
map은 배열에 새로운 규칙을 적용해서 새로운 배열로 만들어준다.
reduce는 배열 내의 요소를 새로운 규칙을 적용해서 하나의 값으로 반환한다.
이렇게 이해하고 있다.
map은 reduce를 하는 규칙으로 적용할 것이고, 그래서 매개변수에 reduce를 한다.
reduce에는 어떤 규칙을 적용해서 하나로 만들 수 있을까?
똑같이 검사해서 있으면 그 값을 더하고, 아닐 경우 0을 더하는 것이다.
array.reduce(callback[, initialValue])
reduce에는 크게 2가지의 인자를 받을 수 있다.
그리고 callback의 인자로 4가지, initialValue의 인자로 1가지를 받을 수 있다.
- accumulator: 누적값(이전 콜백의 반환값 또는 초기값)입니다.
- currentValue: 현재 처리 중인 요소의 값입니다.
- currentIndex: 현재 처리 중인 요소의 인덱스입니다.
- array: reduce() 메서드가 호출된 배열입니다. 콜백 함수는 누적값을 반환해야 합니다.
- initialValue (옵션): 초기값으로 사용될 값입니다. 생략할 경우 배열의 첫 번째 요소가 초기값으로 사용됩니다.
앞의 2개의 인자인 누적값과 처리중인 요소를 사용하였다. photo의 값들을 하나로 합칠 것이다.
a에 c를 더해줄 것인데, photo의 값을 name에서 찾고 해당하는 인덱스값을 구해서
yearning의 인덱스값으로 사용하거나, 아니면 0을 사용했다. 그리고 그 값을 더해주었다.
<코멘트>
map,reduce를 사용하다가 막힌 부분이 배열에 해당 값이 없을 때 undefined를 반환하니까
or 개념을 생각하지 못해서 그 부분을 어떻게 해결할지 막막해서 다른 방법을 찾다가
각각 값을 더해주는 방법으로 구했는데, 여기에서 or 0 개념을 자연스럽게 넣게 되었다.
이후 내가 map, reduce가 어려워서 다른 방법을 쓰게 된게 아니였구나.
근본적인 해결점을 찾게 되어서 다시 풀어보게 되었다.
'개발 > 코딩테스트' 카테고리의 다른 글
[백준 | JavaScript] 10988 팰린드롬인지 확인하기 (1) | 2023.05.21 |
---|---|
[백준 | JavaScript] 2908 상수 (0) | 2023.05.21 |
[프로그래머스 | JavaScript] 가장 가까운 같은 글자 (0) | 2023.05.20 |
[백준 | JavaScript] 1152 단어의 개수 (1) | 2023.05.19 |
[프로그래머스 | JavaScript] 크기가 작은 부분 문자열 (0) | 2023.05.18 |