object 접근, 조작 / array와 비교

·2022년 9월 21일
0

replit을 풀다가 오래고민했던 문제가 있어서 정리한다.

const getExamResult = (scores, requiredClasses) => {}

완성하기


인자 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
.
.
.
"F" => 0
  1. 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
}

의도한대로 잘 실행되었다.


아직은 비슷한 코드들을 반복문을 활용해 줄이는것이 헷갈리고 구체적인 방법을 떠올리는데 시간이 오래 걸리지만 "이대로 계속 하다보면 늘겠지"라는 마음가짐으로 열심히 해야겠다.

0개의 댓글