replit을 풀다가 오래고민했던 문제가 있어서 정리한다.
const getExamResult = (scores, requiredClasses) => {}
완성하기
인자
scores
는 아래와 같은 객체이며, 객체의 요소의 개수 및 키의 이름들은 달라질 수 있고, 객체의 값은 다음 9가지 문자열 중에서 하나를 가지고 있다.
'A+', 'A', 'B+', 'B', 'C+', 'C', 'D+', 'D', 'F'
{ '생활속의회계': 'C', '논리적글쓰기': 'B', '독일문화의이해': 'B+', '기초수학': 'D+', '영어회화': 'C+', '인지발달심리학': 'A+', }
인자
requiredClasses
는 아래와 같이 문자열로 된 배열이다.['영어회화', '기초수학', '공학수학', '컴퓨터과학개론']
조건
scores
객체가 가지고 있는 키들은 새로운 객체에 포함되어야 한다. 단, 그 값들은 다음 원리에 따라 숫자로 바뀌어 할당되어야 한다."A+" => 4.5 "A" => 4 "B+" => 3.5 . . . "F" => 0
requiredClasses
배열의 요소로는 존재하지만,scores
의 키로는 존재하지 않는 항목이 있다면, 해당 요소는 0을 값으로 가지는 새로운 객체의 키가 된다.
const getExamResult = (scores, requiredClasses) => {
let result = {};
for (let key in scores) {
const value = scores[key];
}
}
먼저 함수를 통해 리턴할 빈 객체인 result
를 만들어주고 scores
객체의 key의 개수만큼 반복될 반복문을 작성하였고, 그 안에서 scores
객체의 값을 불러오기위해 변수value
를 만들었다.
반복문을 통해 구현하고자 한 기능은 scores
객체를 돌면서 키의 값을 확인하여 알파벳 점수를 숫자 점수로 변환하여 result
객체에 해당 키와 값을 넣어주는 것이였고, 아래와 같이 작성했다.
let result = {};
for(let key in scores) {
const value = scores[key];
if (value === "A+") {
result[key] = 4.5;
} else if (value === "A") {
result[key] = 4;
.
.
.
} else if (value === "F") {
result[key] = 0;
}
}
조건문을 통해 scores
의 모든 값을 하나하나 비교해가며 등급에 맞는 점수를 부여하며 result
객체를 채우는 코드가 완성되었다.
코드가 너무 길고 지저분하지만 일단 모든 기능을 완성하고 줄이는 방법을 고민해보기로 했다.
다음은 조건2의 기능을 구현할 차례다.
위의 반복문 다음에 아래의 코드를 추가했다.
const scoreskeys = Object.keys(scores);
const notIclude = requiredClasses.filter(el => !scoreskeys.includes(el));
for (let i in notInclude) {
result[notInclude[i]] = 0;
}
먼저 scores
객체의 키들과 requiredClasses
의 요소들을 비교하기 위해서 Object.keys()
메소드를 이용하여 scores
의 키들을 요소로 가진 배열을 만들어 scoreskeys
변수에 저장했고, .filter()
메소드를 이용해 requiredClasses
의 요소들 중 scoreskeys
에 존재하지 않는 요소만 남겨서 만든 배열을 notInclude
변수에 저장했다.
그리고 그 배열을 이용해서 result
에 0을 값으로 가지는 키들을 추가해주는 반복문을 작성했다.
마지막으로 result
객체만 return 해주면 코드는 완성이지만 나는 저 위에 지저분하게 많은 조건문들을 줄여주고싶었다.
지금 내가 사용해야 할 것은 반복문이라는것을 알고있었지만 어떤식으로 활용해야할지 고민하다가
겨우 떠올린 아이디어는 숫자로 된 점수들을 요소로 가진 배열과, 등급을 요소로 가지는 배열을 만들고, 후자의 배열을 scores
의 값들과 비교하여 그 값에 해당하는 등급의 index로 같은 index의 점수를 result
에 값으로 넣어주는 것이였다.
const numericScores = [4.5, 4, 3.5, 3, 2.5, 2, 1.5, 1, 0]; // 숫자 점수를 담은 배열
const grade = ["A+", "A", "B+", "B", "C+", "C", "D+", "D", "F"]; // 등급을 담은 배열
for (let i = 0; i < grade.length; i++) {
result[key] = numericScores[i];
}
전보다 많이 깔끔해진것같아 뿌듯하다.
최종 완성된 코드는 아래와 같다.
const getExamResult = (scores, requiredClasses) => {
let result = {};
for (let key in scores) {
const value = scores[key];
const numericScores = [4.5, 4, 3.5, 3, 2.5, 2, 1.5, 1, 0];
const grade = ["A+", "A", "B+", "B", "C+", "C", "D+", "D", "F"];
for (let i = 0; i < grade.length; i++) {
if (value === grade[i]) {
result[key] = numericScores[i];
}
}
}
const scoreskeys = Object.keys(scores);
const notInclude = requiredClasses.filter(el => !scoreskeys.includes(el));
for (let i in notInclude) {
result[notInclude[i]] = 0;
}
return result;
}
console.log(getExamResult({
'생활속의회계': 'C',
'논리적글쓰기': 'B',
'독일문화의이해': 'B+',
'기초수학': 'D+',
'영어회화': 'C+',
'인지발달심리학': 'A+',
}, ['영어회화', '기초수학', '공학수학', '컴퓨터과학개론']))
console.log를 통해 확인해보면
{ '생활속의회계': 2, '논리적글쓰기': 3, '독일문화의이해': 3.5, '기초수학': 1.5, '영어회화': 2.5, '인지발달심리학': 4.5, '공학수학': 0, '컴퓨터과학개론': 0 }
의도한대로 잘 실행되었다.
아직은 비슷한 코드들을 반복문을 활용해 줄이는것이 헷갈리고 구체적인 방법을 떠올리는데 시간이 오래 걸리지만 "이대로 계속 하다보면 늘겠지"라는 마음가짐으로 열심히 해야겠다.