본문 바로가기
코딩/JS

Js문제 오답노트 반장뽑기(reduce(), 배열값 중복 계산)

by 최만규 2022. 8. 10.
728x90

반장이 되고 싶은 해리


여느 때와 같이 문제 푸려던 중 고민 고민해도 어떻게 해야 할지 감이 안 오는 문제가 있었다.

문제의 문제

일단 prompt로 입력을 받을테니 "원범 원범 혜원 혜원 혜원 유진 유진" 이런 식으로 긴 문자열이 될 것이고,

그다음은 split(" ")으로 공백 단위로 쪼개 이름 한 개씩 갖는 문자열 배열을 만들었다. (이름 수를 세고 누가 많은지 계산하기 위해)

배열 중복 값 개수 구하기 검색하니 공통적으로 reduce가 검색되었다.

 

reduce( )

arr.reduce(callback[, initialValue])

 

 reduce는 배열의 각 요소에 대하여 주어진 reducer함수를 실행하고, 하나의 결과값을 반환한다.

여기서 이 reduce함수는 4개의 인자를 가진다.

  1. 누산기 (acc) : 콜백의 반환값을 누적함
  2. 현재 값 (cur) : 처리할 현재 요소
  3. 현재 인덱스 (idx) : 처리할 현재 요소의 인덱스 (intialValue를 제공했으면 0, 아니면 1부터)
  4. 원본 배열 (src) : reduce()를 호출한 배열

 

최초 호출시는 다음과 같다.

intialValue를 제공 o: acc == intialValue값 cur == 배열의 첫 번째 값

intialValue를 제공x : acc == 배열의 첫 번째 값 cur == 두 번째 값

 

MDN에서 보여주는 다음 예제를 보자.

[0, 1, 2, 3, 4].reduce(function(accumulator, currentValue, currentIndex, array) {
  return accumulator + currentValue;
});

from "https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce"

intialValue는 없기에 처음 호출에서  acc는 배열의 첫 번째 값이 되고,  cur은 두 번째 값인 1이 된 것을 볼 수 있다.

순차적으로 2, 3, 4번째 index에 접근해 accumulator에서 1(0+1), 3(1+2), 6(3+3)까지 누적한다.

그다음 마지막 반환 값은 10이 된다. acc(6) + cur(4) => 10

 

반장선거 코드 

const cand = prompt("총 투표 현황을 적어주세요").split(" ");
let result = {};
let winner = "";

for (let index in cand) {
  let val = cand[index];
  result[val] = result[val] === undefined ? 1 : result[val] = result[val] + 1;
}
winner=Object.keys(result).reduce(function(a, b){
    return result[a]> result[b]? a:b
});
console.log(`${winner}(이)가 총 ${result[winner]}표로 반장이 되었습니다. `);

line:1 prompt로 이름들을 입력받는다. ex) 민규 수진 수진 민규 민규  split으로 이름을 item으로 갖는 배열을 만들어 cand에 할당.

line: 2, 3 result 객체 생성(이름과 이름이 불린 개수를 저장), winner 빈 문자열 생성

for ..in 문  cand 객체 안의 key를 index가 받으면서 루프 문이 진행된다. val에 index에 해당하는 cand객체의 값을 할당한다.

result객체의 val키를 가진 값은 result[val]===라면 1을 반환 (맨 처음 보는 이름이라면 값에 1을 넣고 그렇지 않으면 값 +1을 한다.)

다음 표를 보면서 for ..in 문의 진행을 전체적으로 이해해보자.

실행 cand val result
1 cand=[ "민규", "수진", "수진", "민규", "민규" ] "민규" { "민규" : 1 }
2 cand=[ "민규", "수진", "수진", "민규", "민규" ] "수진" { "민규" : 1, "수진" : 1 }
3 cand=[ "민규", "수진", "수진", "민규", "민규" ] "수진" { "민규" : 1, "수진" : 2 }
4 cand=[ "민규", "수진", "수진", "민규", "민규" ] "민규" { "민규" : 2, "수진" : 2 }
5 cand=[ "민규", "수진", "수진", "민규", "민규" ] "민규" { "민규" : 3, "수진" : 2 }

 

여기까지의 과정을 잘 기억하며 위에서 배운 reduce를 배우는 다음 라인으로 이동해보자.

 

다음은 이제 누가 반장이 될 것인가를 결정짓는 코드이다. 

Object.keys(객체) => 객체의 키(이름) 들을 나타내는 문자열 배열을 만든다.

 

ex) arr = { name : "minkyu", height : 177, mbti : "entp"}

Object.keys(arr)는   ['name', 'height', 'mbti']가 된다.

 

즉 result의 키인 "민규", "수진"들을 들고와 result [민규]와 result [수진]을 비교해 더 큰 key를 반환하도록 한다.

그러면 결국 값이 3 : 2로 "민규"가 더 큰 값을 가지고 있기에 winner에는 "민규"가 반환된다.

마지막에 log를 통해 민규(이)가 총 3표로 반장이 되었습니다. 이 출력되게 된다.

 

객체에 대한 개념이나 관련 메서드들을 공부를 꾸준히 해야겠다. 정진 또 정진 !

주야장천 불철주야 아멘 나무아미타불 코쿤캅

 

728x90

'코딩 > JS' 카테고리의 다른 글

JS문제풀이 (로꾸거배열) + (&, |, 연산자 단축평가)  (1) 2022.08.08
별 탑 쌓기 문제해결  (4) 2022.08.07
Js복습 pt.6 NPM  (1) 2022.08.04
Js복습 pt.5 module system  (3) 2022.08.01
(부록)스터디 윗 미  (1) 2022.07.31