서로 다른 객체의 값을 변경하기 (A.K.A 학점계산기)

LSA·2022년 2월 25일
0

javascript+a

목록 보기
2/4
post-custom-banner

자바스크립트에 익숙해지기 위해 과제 문제들을 점차 풀어나가는 도중..

큰일났습니다.
어떻게 풀어야 할지 감도 잡히지 않습니다.
그래도 일단 흐름부터 정해봅니다.

01. 흐름 설정

  1. {A+ : 4.5 , A : 4…}와 같이 알파벳 점수를 숫자 점수로 변환하는 객체 scoreToNumber생성
  2. 기존 scores에 있는 value값을 scoreToNumber의 value로 전환
  3. requiredClasses로 받은 배열 엘리먼트를 검사하여 scores 객체에 없는 이름을 추가
  4. 수정된 scores 객체 변환

02. 코드를 작성했더니 실패함

  • 샘플로 넣을 객체와 배열
let sampleObj ={
    '생활속의회계': 'C',
    '논리적글쓰기': 'B',
    '독일문화의이해': 'B+',
    '기초수학': 'D+',
    '영어회화': 'C+',
    '인지발달심리학': 'A+',
  }
  
let sampleClass = ['영어회화', '기초수학', '공학수학', '컴퓨터과학개론']

02-1. 함수와 객체 설정

const getExamResult = (scores, requiredClasses) => {
  const scoreToNumber = {
    'A+' : 4.5,
    'A' : 4,
    'B+' : 3.5,
    'B' : 3,
    'C+' : 2.5,
    'C' : 2,
    'D+' : 1.5,
    'D' : 1,
    'F' : 0
  };
  let myScore = Object.values(scores)
}
  • 함수 getExamResult는 파라미터로 scores, requiredClasses 를 받습니다. 여기서 scores가 샘플로 지정해둔 객체고, requiredClasses는 샘플로 지정해둔 배열입니다.
  • scoreToNumber는 알파벳 점수를 숫자 점수로 변환한 객체입니다.
  • 변수 myScore는 샘플로 들어온 객체의 value 값들이 될 겁니다.

02-2. 반복문 설정

여기에다가 밑에 반복문을 더 추가해줍니다.

for(key in scores){
    scores[key] = Object.values(scoreToNumber)
    console.log(myScore)
  }
  
 return scores 
  • scores 객체의 key마다 scoreToNumbervalue 값으로 변환합니다. 결과를 확인하기 위해 myScore를 콘솔에 찍으라고 했어요.

결과는?

어..뭔가 망한 것 같습니다.

02-3. 망해서 조언을 받았다

여기서 사고가 정지해버려 커뮤니티에서 도움을 받았습니다.

lsa님 안녕하세요! 현재 코드에서 console.log(myScore)을 찍게 되면 scores에 할당 되어 있는 값이 6개이므로 console이 6개 찍히는 걸 확인하실 수 있습니다.

빈 객체인 result를 먼저 선언해준 다음 scoreToNumber 변수를 선언해주고 아래에 for in문을 사용하여 마지막에 result를 반환해주시면 되는데 scores 객체의 key마다 scoreToNumber의 value 값으로 변환해주는 생각은 맞게 하셨는데 코드를 잘못 작성하신 것 같아요!

scores[key] = Object.values(scoreToNumber)로 작성하게 되면 ‘생활속의회계’ 와 4.5 가 같아진다는 의미이므로 스코어의 value값과 비교하게끔 수정하시면 될 것 같습니다.


글에서 어떤 부분을 이야기하시는지는 어느정도 알겠는데, 이걸 보고 어떤 코드를 짜야할지 떠오르지 않아 막막해졌습니다.
...어쩔 수 없이 치트키로, 정답을 적은 동기분들의 코드를 가져왔어요!

03. 적선받은 코드 해석

동기 J님

const getExamResult = (scores, requiredClasses) => {
  // 객체를 변수에 담아 배열로 변환
 const keys = Object.entries(scores);

 // 학점을 점수로 변환 
  for(let i in keys){
    switch (keys[i][1]) {
      case "A+" :
      keys[i][1] = 4.5;
      break;
      case "A" :
      keys[i][1] = 4;
      break;
      case "B+" :
      keys[i][1] = 3.5;
      break;
      case "B":
      keys[i][1] = 3;
      break;
      case "C+":
      keys[i][1] = 2.5;
      break;
      case "C":
      keys[i][1] = 2;
      break;
      case "D+" :
      keys[i][1] = 1.5;
      break;
      case "D":
      keys[i][1] = 1;
      break;
      default:
      keys[i][1] = 0;
    }  
  }

// 변환한 배열을 담을 새로운 객체
const newObj = Object.fromEntries(keys);

// 새로운 객체에 키 값 추가하는 함수 
for ( let i in requiredClasses) {
  if (newObj[requiredClasses[i]] === undefined){
    newObj[requiredClasses[i]] = 0;
  } 
}
  return newObj;
}

저처럼 객체를 만들어두지 않고, switch 문을 이용해서 알파벳을 학점으로 바꿔주었네요!
처음부터 해석해볼게요.

const keys = Object.entries(scores);

변수 keys는 인자로 들어온 객체 scores의 프로퍼티들을 가져와 배열로 만듭니다.
이렇게!
그리고 keys의 요소 개수만큼 반복하면서 값들을 대조할텐데,

 for(let i in keys){
    switch (keys[i][1]) {
      case "A+" :
      keys[i][1] = 4.5;
      break;
      case "A" :
      keys[i][1] = 4;
      break;
      case "B+" :
      keys[i][1] = 3.5;
      break;
      case "B":
      keys[i][1] = 3;
      break;
      case "C+":
      keys[i][1] = 2.5;
      break;
      case "C":
      keys[i][1] = 2;
      break;
      case "D+" :
      keys[i][1] = 1.5;
      break;
      case "D":
      keys[i][1] = 1;
      break;
      default:
      keys[i][1] = 0;
    }  
  }

switch의 조건으로 keys의 i번째 배열의 1번 요소값을 숫자로 바꿔 주셨네요! 굉장해요!

const newObj = Object.fromEntries(keys);

여기서 새로운 메소드가 등장합니다.fromEntries네요. 설명은 여기서
쉽게 말하자면, Array를 Object로 바꿔주는 그런 메소드입니다...
이 한줄로,keys라는 배열들을 객체로 바꿔버렸습니다.

이제 다음 인자로 받아온 requiredClasses를 봅시다.

for ( let i in requiredClasses) {
  if (newObj[requiredClasses[i]] === undefined){
    newObj[requiredClasses[i]] = 0;
  } 
}
  return newObj;
}

requiredClasses의 요소 개수만큼 실행하는 반복문입니다.newObj객체에 requiredClasses에 없는 과목명이 있다면,(그러니까 새로운 과목명이 추가될때)newObj에는 없는 키가 추가되며 값을 0으로 만들어버리는겁니다.

요약

  • 인자로 들어온 객체를 배열로 바꿔준다.
  • 반복문과 switch문으로 객체의 값들을 숫자로 바꿔준다.
  • 그 객체를 다시 배열로 바꿔준다.
  • 객체 내에 requiredClasses에서 새로운 이름이 있는지 비교하고, 없다면 객체에 그 이름을 가진 key를 생성 후 값을 0으로 정해준다.

멋진 코드였어요, J님!
다음 코드로 넘어갑니다.

동기 C님

const getExamResult = (scores, requiredClasses) => {
  const result = {};
  let scoreChange = {
    'A+' : 4.5,
    'A' : 4,
    'B+' : 3.5,
    'B' : 3,
    'C+' : 2.5,
    'C' : 2,
    'D+' : 1.5,
    'D' : 1,
    'F' : 0
  };

  for (let i in requiredClasses) {
    const classesAdded = requiredClasses[i]
    //ex) classAdded = '영어회화'
   
    result[classesAdded] = 0;
    //ex) result['영어회화'] = 0;
  }

  for (let key in scores) {
    const scoresBefore = scores[key];
     //ex) scoresBefore = scores['생활속의 회계'] => C
    const scoresAfter = scoreChange[scoresBefore];
     // ex) scoresAfter = scoreChange[C] => scoresAfter = 2
    result[key] = scoresAfter
    //result['생활속의 회계'] = 2
  }

  return result;
}

아까보다는 좀더 짧아졌습니다.

 const result = {};
  let scoreChange = {
    'A+' : 4.5,
    'A' : 4,
    'B+' : 3.5,
    'B' : 3,
    'C+' : 2.5,
    'C' : 2,
    'D+' : 1.5,
    'D' : 1,
    'F' : 0
  };

저처럼 알파벳을 숫자로 변환한 객체를 만들어주고, result라는 빈 객체를 만들었어요.

for (let i in requiredClasses) {
    const classesAdded = requiredClasses[i]
    //ex) classAdded = '영어회화'
   
    result[classesAdded] = 0;
    //ex) result['영어회화'] = 0;
  }

requiredClasses 배열 반복부터 시작합니다.
변수 classesAddedrequiredClasses의 i번째 요소입니다.
친절하게 주석으로 결과도 달아주셨네요!
그다음에 객체 result의 key 값에 classesAdded를 추가 후 일단 기본값을 0으로 지정하였어요.

for (let key in scores) {
    const scoresBefore = scores[key];
     //ex) scoresBefore = scores['생활속의 회계'] => C
    const scoresAfter = scoreChange[scoresBefore];
     // ex) scoresAfter = scoreChange[C] => scoresAfter = 2
    result[key] = scoresAfter
    //result['생활속의 회계'] = 2
  }

  return result;

다음 인자로 받은 scores에서의 반복문입니다.
변수 scoresBefore는 인자로 들어온 scores의 각 value값입니다. 여기서 key를 console로 출력하면 이렇게 나오기 때문에..
주석에 나온 것처럼 scores['생활속의 회계'] 형태가 가능한겁니다.
변수 scoresAfter는 앞서 만들어둔 학점변환 객체에서 scoresBefore 이름을 가진 key값을 찾아냅니다.
과목명만 있고 값들은 전부 0이었던 객체 result에다가,scoresAfter의 값을 집어넣습니다.
자동적으로 requiredClasses 배열에만 있던 과목명은 값이 0인 상태를 유지하겠네요!

요약

  • 최종 반환할 빈 객체 하나와, 알파벳을 숫자로 변환할 객체를 만들어준다.
  • 빈 객체에 requiredClasses의 과목들을 미리 추가해준다. 값은 전부 0으로 통일
  • scores의 각 value 값들을 변수로 선언
  • 숫자변환 객체에서 scores의 각 value 값들을 찾아낸다. 이 과정에서 자연스럽게 숫자로 변수들이 선언된다.
  • result 객체에서 과목명이 일치하는 것들만 새로 값을 바꿔준다.


이런 엄청난 흐름을 간단한 코드로 표현해내신 C님, 존경합니다..

마무리

동기 두 분의 코드를 참고하여, 이런 문제가 나와도 당황하지 않고 keyvalue 값들을 변수로 바꿔 응용하는 것에 익숙해져야겠네요!

profile
진짜 간단하게 작성한 TIL 블로그
post-custom-banner

0개의 댓글