JS | 과목별 학점 알파벳➡숫자 변경 함수 만들기 (re bracket notation, 순회)

DongHee Kim·2021년 8월 9일
2

Javascript

목록 보기
7/9
post-thumbnail

문제풀이의 목적

  • 객체의 key값에 접근하는 방법인 bracket notation과 dot notation 에 대해 알아본다.
  • 반복문을 통해 객체의 값을 순회할 수 있다.
  • 객체의 속성을 종합하여 다른 객체의 값을 할당할 수 있다.

문제

아래 설명을 읽고 getExamResult 함수를 구현하세요.
인자 scores 는 다음과 같은 객체입니다. 객체의 요소의 갯수 및 키의 이름들은 달라질 수 있습니다. 객체의 값은 다음 9가지 문자열 중에서 하나를 가지고 있습니다.

'A+', 'A', 'B+', 'B', 'C+', 'C', 'D+', 'D', 'F'

scores = {
  '생활속의회계': 'C',
  '논리적글쓰기': 'B',
  '독일문화의이해': 'B+',
  '기초수학': 'D+',
  '영어회화': 'C+',
  '인지발달심리학': 'A+',
}

인자 requiredClasses 는 다음과 같이 문자열로 된 배열입니다.

['영어회화', '기초수학', '공학수학', '컴퓨터과학개론']

다음 조건을 만족하는 객체를 리턴하도록 함수를 구현해주세요.

scores 객체가 가지고 있는 키들은 새로운 객체에 포함되어야 합니다. 단, 그 값들은 다음 원리에 따라 숫자로 바뀌어 할당되어야 합니다.

A+ => 4.5
A => 4
B+ => 3.5
B => 3
C+ => 2.5
C => 2
D+ => 1.5
D => 1
F => 0

requiredClasses 배열의 요소로는 존재하지만, scores의 키로는 존재하지 않는 항목이 있다면, 해당 요소는 새로운 객체의 키가 되고, 값으로 0을 가져야 합니다. 위에서 예시로 묘사된 객체와 배열이 인자로 들어왔다면, 다음과 같은 객체과 리턴됩니다. 요소간 순서는 다를수 있지만, 채점에 무관합니다.

{
  '생활속의회계': 2,
  '논리적글쓰기': 3,
  '독일문화의이해': 3.5,
  '기초수학': 1.5,
  '영어회화': 2.5,
  '인지발달심리학': 4.5,
  '공학수학': 0,
  '컴퓨터과학개론': 0,
}

풀이과정

새로운 객체를 만들어 값을 넣고.. 다른 객체와 값을 비교하고.. 또 할당하고..
가만히 앉아서 고민하다보니 결국 생각이 꼬여버려 화이트보드에 차근차근 정리해내 풀어냈다.
꼬박 2시간을 고민했지만 결국 스스로의 힘으로 풀어내 뿌듯한 성취감을 맛봤다.

혼자 고민해 풀어낸 사고의 흐름과, 세션에서 알게된 풀이 방법을 함께 정리해보자.

나의 풀이

사고의 흐름

step 1

scores객체의 key(과목명)value(알파벳 학점)값을 각각 배열화 시키고,
value(알파벳 학점) 값을 숫자로 변환한 새로운 배열 numValues(숫자 학점)를 만들었다.

// scores의 key와 value 값들 배열화
const keys = Object.keys(scores);
const values = Object.values(scores);


// values값 숫자로 바꾸기
const numValues = values.map(x =>
{if(x === 'A+'){return 4.5}
else if(x === 'A'){return 4}
else if(x === 'B+'){return 3.5}
else if(x === 'B'){return 3}
else if(x === 'C+'){return 2.5}
else if(x === 'C'){return 2}
else if(x === 'D+'){return 1.5}
else if(x === 'D'){return 1}
else if(x === 'F'){return 0}
});

step 2

비어있는 새로운 객체 obj를 만들어 {과목명 : 숫자 학점} 의 형태로 값을 할당했다.
그럼 우선 requiredClasses 를 고려하지 않은, 학점을 문자 >> 숫자로 변환한 객체 구현은 완료!

// {scores 과목:숫자점수} 객체 생성 및 값 할당 
const obj = {};
for (let i in keys){
obj[keys[i]] = numValues[i];};

step 3

requiredClasses 객체의 key(과목명) 중 scores에 포함되지 않는 과목명의 value값(숫자 학점)은 0을 주어야한다.
{scores과 requiredClasses의 차집합 과목명 : 0} 형태를 가진 새로운 객체(plusObj)를 생성하고, 과목명의 차집합을 구해 plusObj에 할당했다.

과목명의 차집합은 filter() 메서드를 활용해 scores의 key값에 포함되지않는 새로운 배열을 반환하는 방식을 택했다.
let difference = a.filter(x => !b.includes(x))

// {scores & requiredClasses 차집합 과목 : 0} 객체(plusObj) 생성
const plusObj = {};  
const minor = requiredClasses.filter(x => !keys.includes(x));

//plusObj에 key(minor):value(0) 값 할당
for(let i in minor){
  plusObj[minor[i]]=0;
};

step 4

{scores의 과목명 : 숫자 학점}인 obj객체와 {scores/requiredClasses의 차집합 과목명 : 0}인 plusObj를 합친 객체 final을 만들고 반환한다.

// 기존 obj객체와 plusObj객체를 합치고 반환
const final = Object.assign(obj,plusObj);
return final;

정답 코드

const getExamResult = (scores, requiredClasses) => {

// scores의 key와 value 값들 배열화
const keys = Object.keys(scores);
const values = Object.values(scores);


// values값 숫자로 바꾸기
const numValues = values.map(x =>
{if(x === 'A+'){return 4.5}
else if(x === 'A'){return 4}
else if(x === 'B+'){return 3.5}
else if(x === 'B'){return 3}
else if(x === 'C+'){return 2.5}
else if(x === 'C'){return 2}
else if(x === 'D+'){return 1.5}
else if(x === 'D'){return 1}
else if(x === 'F'){return 0}
});


// {scores 과목:숫자점수} 객체 생성 및 값 할당 
const obj = {};
for (let i in keys){
obj[keys[i]] = numValues[i];};


// {scores & requiredClasses 차집합 과목 : 0} 객체(plusObj) 생성
const plusObj = {};  
const minor = requiredClasses.filter(x => !keys.includes(x));

  
//plusObj에 key(minor):value(0) 값 할당
for(let i in minor){
  plusObj[minor[i]]=0;
};

  
// 기존 obj객체와 plusObj객체를 합치고, 반환
const final = Object.assign(obj,plusObj);
return final;

느낀 점

  • 알파벳 학점을 숫자 학점으로 바꾸는 과정에서 scores의 값을 배열로 가져오고, 조건에 맞추어 새로운 배열을 만드는 map메서드를 이용했는데, 하나하나 모두 바꾸다보니 그 과정이 길고 복잡했다.
  • 변수를 이용해서 객체에 접근할 때에는 dot notation이 아닌 bracket notation이 필요하다는 걸 이론 상으로는 알고있었지만, 문제를 풀어보며 체화하는 시간을 가졌다.

세션 풀이

Q&A 세션에서 본 문제의 풀이 과정이 소개되어서, 나와 어떻게 다른지 알아보았다.

사고의 흐름 & 정답코드

const getExamResult = (scores, requiredClasses) => {
  
  // 비어있는 새로운 객체object 만들기
  const obj = new Object();
  
  
  // {알파벳 학점 : 숫자 학점} 값의 객체 만들기
  const gradeMap = {
    "A+":4.5,
    "A":4,
    "B+":3.5,
    "B":3,
    "C+":2.5,
    "C":2.0,
    "D+":1.5,
    "D":1,
    "F":0
  }
  
  
  // scores[key](알파벳 학점)를 변수 grade에 할당
  // 빈 객체 obj의 key에는 scores의 key(과목명)를, 값에는 gradeMap의 값(숫자 학점) 할당 
  for (let key in scores) {
    const grade = scores[key];
    obj[key] = gradeMap[grade];
  }
  
  
  // requiredClasses의 값(과목명)을 변수 ClassName에 할당
  // obj의 key 중 ClassName의 값이 없으면 undefined가 반환되니, 그럴 경우 값에 0할당
  // 최종 답안인 obj 리턴
  for (let i = 0; i < requiredClasses.length; i++) {
    const className = requiredClasses[i];
    if (obj[className] === undefined) {
      obj[className] = 0;
    }
  }
  return obj;
}

느낀 점

  • 내 풀이와 달리 {알파벳 학점:숫자 학점}의 객체gradeMap을 만들어서 새로운 빈 객체에 for문으로 key,value값을 더 간단하게 할당했다. 객체의 속성을 더 유용하게 활용한 셈.

  • 또 나는 scores와 requiredClasses의 과목명 차집합으로 이루어진 객체를 다시 만들어 이전의 객체와 합친 값을 최종으로 반환했는데, 여기선 그런 과정없이 객체의 속성을 활용해 값이 undefined가 나올 경우 값에 0을 할당하는 방법을 사용했다.

profile
일상의 성실이 자존감을 만드는 성취주의자

1개의 댓글

comment-user-thumbnail
2021년 8월 14일

분할 정복 알고리즘의 과정을 명확하게 볼 수 있어서 좋은 것 같아요!
화이트 보드에 작성하시면서 분석하고 문제 해결해나가는 모습이 👍

답글 달기