[replit 30] Object3 - 객체 key를 변수로 할당하기

Joe·2022년 10월 20일
0

과제내용

### 아래 설명을 읽고 `getExamResult` 함수를 구현하세요.

인자 `scores` 는 다음과 같은 객체입니다. 객체의 요소의 갯수 및 키의 이름들은 달라질 수 있습니다. 객체의 값은 다음 9가지 문자열 중에서 하나를 가지고 있습니다.

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

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

```

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

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

```

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

1. `scores` 객체가 가지고 있는 키들은 새로운 객체에 포함되어야 합니다. 단, 그 값들은 다음 원리에 따라 숫자로 바뀌어 할당되어야 합니다.
    - A+ => 4.5
    - A => 4
    - B+ => 3.5
    - B => 3
    - C+ => 2.5
    - C => 2
    - D+ => 1.5
    - D => 1
    - F => 0
2. `requiredClasses` 배열의 요소로는 존재하지만, `scores`의 키로는 존재하지 않는 항목이 있다면, 해당 요소는 새로운 객체의 키가 되고, 값으로 0을 가져야 합니다. 위에서 예시로 묘사된 객체와 배열이 인자로 들어왔다면, 다음과 같은 객체과 리턴됩니다. 요소간 순서는 다를수 있지만, 채점에 무관합니다.
    
    ```
    {
      '생활속의회계': 2,
      '논리적글쓰기': 3,
      '독일문화의이해': 3.5,
      '기초수학': 1.5,
      '영어회화': 2.5,
      '인지발달심리학': 4.5,
      '공학수학': 0,
      '컴퓨터과학개론': 0,
    }
    
    ```
    

⚠️ 과제를 해결하면서의 과정을 적었을 뿐 확실하지 않은 지식과 방법일 수 있기에 참고만 바립니다⚠️

<1차코딩 결과 - 미완성>

let scoreObj = {
'생활속의회계': 'C',
'논리적글쓰기': 'B',
'독일문화의이해': 'B+',
'기초수학': 'D+',
'영어회화': 'C+',
'인지발달심리학': 'A+',
}
let requiredArr = ['영어회화', '기초수학', '공학수학', '컴퓨터과학개론'];
console.log(getExamResult(scoreObj,requiredArr));
const getExamResult = (scores, requiredClasses) => {
const obj={};
for (let key in scores) {
	const value = scores[key];
	obj.key = function convertToNum(){
const numericScores = {
	'A+':4.5,
	'A':4,
	'B+':3.5,
	'B':3,
	'C+':2.5,
	'C':2,
	'D+':1.5,
	'D':1,
	'F':0
			}
return numericScores.value;
		}
	}
return obj;
}

거의 40분의 고민과 노트작성을 통해 문제가 요구하는 바를 깨닫고 정말 하나하나 key와 value를 분석해서 코드를 적어내려갔었다.

공부한 내용을 바로바로 적용해서 코드를 작성하려고 하니 쉽지 않았다.

먼저 이해하기로, getExamResult라는 함수를 통해 새로운 obj를 나타내는 것이 문제였다.

그 obj의 key값은 score의 key값에서 오게되고 obj의 value는 score의 value를 어떠한 과정을 통해 숫자로 변환시켜 오게되는 것이라는 것을 오랜고민 끝에 이해할 수 있었다.

그럼 먼저 obj의 key값에 score에 key을 받아서 넣어야하는데 어떻게 가능할까?라는 생각부터 시작되었고 그것을 적어내려갔다.

  • 객체의 문자열 key를 순회하는 문법 for-in을 사용했다. scores라는 객체의 key값을 받았고 그것을 obj의 key에 대입하려했다.
for(let key in scores){
	obj.key = scores의 key
}

당연히 제대로 작동되지 않았다…

이유는?

💡 key는 문자열의 key가 아닌 변수를 통해 받아온 것인데 대괄호 없이 dot(.)으로 value를 대입하려했다….그러니 obj이라는 객체안에 { key : scores key} 이렇게 값이 정해진거야..

아래의 예를 한번 보도록 하자.

const information = {
	name: 'Joe'
}

let a = 'age';
let b = 20;

information[a]= b;
information.age = 20;

객체의 키를 변수를 통해 받아온다면 꼭!! 대괄호 안에 넣어서 표현해줘야한다. 두번째 방법으로 하게 된다면 key와 value는 항상 정해져 있게 되는 것이다.

그리고 다음으로 가장 어렵고 내가 모르는게 무엇인지도 모르는 부분이 바로 requiredClasses 배열의 요소로는 존재하지만, scores 의 키로는 존재하지 않는 항목이 있다면! 이 부분이였다.

즉, 배열에 있는 요소들을 가지고 score라는 객체의 key와 비교를 해야한다…?

어떻게 배열에 모든 요소들을 꺼낼까 생각했었고 forEach()가 배열 요소를 하나하나 꺼내어 각각에 대해 실행하는 함수이기에 사용했다.

여기까지는 Ok. 그 뒤로 requiredClasses에 있는 각각의 배열의 요소들을 elem의 변수로 받았는데…어떻게 elem(배열의 요소)이 scores라는 객체의 키와 비교를 할 수 있을까…? 여기서 또 한참 생각을 했다.

배열의 요소가 어느 객체 내부에 포함하는지에 대한 것을 찾기 위해 여러가지를 시도해보았다.

  • indexOf
  • includes

등등, 내부에 뭔가 포함하고 있는지 아닌지에 대한 것은 위에 것들을 사용했다는게 얼핏 기억이 나서인지 제일 먼저 떠올랐지만, 전혀 제대로 작동되지 않았다.

그러다 in 연산자 라는 것을 공부하게 되었다.

in 연산자

속성 in 객체명

⭐️⭐️⭐️in 연산자는 명시된 속성이 명시된 객체에 존재하면 true를 반환한다⭐️⭐️⭐️

elem in scores
	// -> 명시된 elem이 명시된 객체 scores에 존재하면...트루...?

문제대로 배열안에 있지만 scores의 키로는 존재하지 않는 항목에 해당 요소는 새로운 객체의 key가 되고 값은 0이 된다고 하니…

if(!(elem in scores)){
obj[elem] = 0;    // 똑같이 obj.elem으로 해서 오류가 났었다... 주의! ⚠️ 

기분이 짜릿했다…뭔가 관통당하는 느낌이랄까..

그 이후로는 scores의 value인 grade들을 숫자로 바꿔주기 위해 convertToNum()을 만들어줬다.

requiredClasses.forEach((elem) => {
      if (!(elem in scores)){
        obj[elem] = 0;   //obj.elem으로도 쓰고 obj.key라고 써서 에러가 발생했었음
      }
      else{
	        obj[key] = function convertToNum(value){
						const numericScores = {
			        'A+':4.5,
			        'A':4,
			        'B+':3.5,
			        'B':3,
			        'C+':2.5,
			        'C':2,
			        'D+':1.5,
			        'D':1,
			        'F':0
				        }
      return numericScores[elem];
				}
      }
    })

사실 처음에는 함수를 forEach()문 안에 선언만 해놓고 왜 작동이 안될까 고민했다.

obj[key] 즉, obj의 값을 받기 위해 아래처럼 선언만 해놓고 호출을 하지 않는 오류를 저질렀다.

아래와같이 함수를 선언하면서 호출하는 방법도 있지만, 그렇게 되면 반복문 안에서 계속해서 convertToNum함수가 돌아가기에 global에 따로 빼서 함수를 선언했다.

<최종코드>


const getExamResult = (scores, requiredClasses) => {
  const obj={};
  for (let key in scores) {
    const value = scores[key];
    requiredClasses.forEach((elem) => {
      if (!(elem in scores)){
        obj[elem] = 0;   //obj.elem으로도 쓰고 obj.key라고 써서 에러가 발생했었음
      }
      else{
        obj[key] = convertToNum(value);
      }
    })
  }
  return obj;
}

function convertToNum(elem){
        const numericScores = {
        'A+':4.5,
        'A':4,
        'B+':3.5,
        'B':3,
        'C+':2.5,
        'C':2,
        'D+':1.5,
        'D':1,
        'F':0
        }
      return numericScores[elem];
    }

let scoreObj = {
  '생활속의회계': 'C',
  '논리적글쓰기': 'B',
  '독일문화의이해': 'B+',
  '기초수학': 'D+',
  '영어회화': 'C+',
  '인지발달심리학': 'A+',
}
let requiredArr = ['영어회화', '기초수학', '공학수학', '컴퓨터과학개론'];
console.log(getExamResult(scoreObj,requiredArr));

<결과값>

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

정말 3시간동안 머리를 감싸며 적고 생각하는 과정은 힘들었지만 그 과정속에서 많은 것들을 배우고 느끼는 것 같다. 손도 못댈것만 같았는데 그래도 하나하나 접근해나아가니 해결해 나갈 수 있었다. 이번 과제를 하며 많이 느낀 것은 “어설프게 아는것” 이였다.

객체의 키를 변수로 할당했을 때의 어떻게 다룰것인가의 방법이라던지 언제 dot을 쓰고 언제 대괄호를 쓰는가에 대한 글만 몇번 읽어봤지 직접 내가 고민해서 사용해보지 않았었다.

단순히 이해하는 것에서 멈추지 않고, “모르면 배우고, 배워서 익히고, 익혀서 먹는” 그런 과정이 얼마나 필요한지 뼈저리게 느끼는 시간이였다. 정리할 내용들이 정말 많지만 놓치지 않고 하나하나 다시 시작해보려한다.

profile
Creator

0개의 댓글