TIL | object 심화

임채현·2022년 1월 4일
0

object 심화

wecode js repl.it 30번을 풀면서 후에 도움될 많은 개념과 내용들을 얻었다.
블로그에 정리를 하고 가면 좋을 것 같다.

객체의 키를 변수로 접근

const information = {
  name: '김개발'
}

const verb = 'developes'
const project = 'facebook'

information[verb] = project // [A]
information.developes = 'facebook' // [B]

객체에 속성을 추가할 때 키를 변수로 받아올 수 있다. [A]와 같은 방법으로 bracket notation을 이용하면 된다. dot notation은 가능하지 않다.
dot notation으로 똑같은 결과를 가져오려면 [B]와 같이 developes를 key로 설정햐여 만들어야한다.
여기서 큰 차이가 발생하는데 dot notation은 키와 값이 항상 정해져 있는 반면 bracket notaton은 변수 verbproject가 가지는 값에 따라 다른 키와 다른 값을 가질 수 있다. 활용도가 더 다양하다는것!

객체 순회하기

객체가 순서가 없고 배열은 순서가 있다!! js를 배우면서 얻었던 중요한 개념 중 하나이다.
따라서 객체는 배열처럼 for문을 사용하여 index를 일일이 돌아볼 수가 없다. index가 없기 때문에!
하지만 객체의 속성과 속성값을 배열로 받을 수 있다면 어떨까?
그러면 객체의 반복문 작성은 가능할지도..?

Object.keys()

  • Object.keys 메소드는 어떤 객체가 가지고 있는 키들의 목록을 배열로 리턴하는 메소드이다.
  • 객체의 내장 메소드가 아니라 객체 생성자인 Object 가 직접 가지고 있는 메소드이다.
const obj = {
  name: 'melon',
  weight: 4350,
  price: 16500,
  isFresh: true
}

Object.keys(obj) // ['name', 'weight', 'price', 'isFresh']

따라서 우린 이 리턴된 키의 배열을 이용하여 반복문을 사용할 수 있다.

const keys = Object.keys(obj) // ['name', 'weight', 'price', 'isFresh']

for (let i = 0; i < keys.length; i++) {
  const key = keys[i] // 각각의 키
  const value = obj[key] // 각각의 키에 해당하는 각각의 값
  console.log(value)
}

각 키에 대한 값을 출력받을 수 있다.
이와 마찬가지로 Object.values, Object.entries와 같은 자매품이 있다.
Object.values는 객체의 키에 대한 값들을 배열로 받고 Object.entries는 배열안에 키의 배열과 값의 배열을 가진 2중구조의 배열을 받는다.

for-in

object의 키와 값을 배열로 변환한 후 for문을 돌리는 경우가 아니더라도 순회가 가능하다.
바로 for-in문을 쓰는것이다!
먼저 array부터 보자면

const arr = ['coconut', 'banana', 'pepper', 'coriander']

for (let i = 0; i < arr.length; i ++) {
  console.log(i)
  console.log(arr[i])
}

굉장히 많이 봐왔던 익숙한 for문이다.
이렇게 첫 인덱스부터 시작하여 1씩 증가하며 끝까지 순회하는 방식의 for문을 다음과 같이 축약할 수 있다.

for (let i in arr) {
  console.log(i)
  console.log(arr[i])
}

정말 간단하게 표현이 가능하여 정말 많이 쓰일 것 같다.
하지만 시작이 끝 인덱스부터거나 2개씩 건너뛰는 등의 다른 경우에는 적용이 불가능하다.
처음에 약간 헷갈렸던게 파이썬에서는 이럴 경우 배열의 요소로 순회를 하는데 js는 반드시 index를 순회한다. 위의 let i = 0; i < arr.length; i ++를 축약한 방식이기 때문이다.

이 방식은 객체에서도 적용할 수 있다.

const obj = {
  name: 'melon',
  weight: 4350,
  price: 16500,
  isFresh: true
}

for (let key in obj) {
  const value = obj[key]

  console.log(key)
  console.log(value)
}

객체를 배열처럼 전부 순회하게 된다.
여기서 주의할 점은 이 방식으로는 키 밖에 순회가 안된다는것이다.
애초에 배열의 인덱스를 순회하는 방식을 축약한 것이기 때문에 for-in문으로 object의 값을 순회할 수는 없다.
하지만 값을 변수로 설정하고 출력하면 각 키에 대한 값을 얻을 수는 있다.

PS) array인 경우에는 for..in사용이 지양된다고 한다. 배열 index는 enumerable한 정수로 된 열거 가능한 속성인데 반해 for in은 정수가 아닌 이름을 가진 속성, 상속된 모든 열거 가능한 속성들을 순회하여 반환하기 때문이다. 오히려 이런점이 object의 key값을 순회가능하게 만들기 때문에 이 점을 이용하여 object의 key를 순회할 때 사용해야겠다.

getExamResult


const getExamResult = (scores, requiredClasses) => {const gradeObj = {'A+': 4.5, 'A': 4.0, 'B+': 3.5, 'B': 3.0, 'C+': 2.5, 'C': 2.0, 'D+': 1.5, 'D': 1.0, 'F': 0};
  const result = {};
  for (let key in scores) {
    result[key] = gradeObj[scores[key]];
  }
  const keyScore = Object.keys(scores)
  for (let i in requiredClasses) {
    if (keyScore.includes(requiredClasses[i])==false) {
      result[requiredClasses[i]] = 0}
  }
  return result
}

이 문제를 푸는데 상당히 오랜 시간이 걸렸다. 꽤 생각하기 어려운 문제였던것 같다.
먼저 문제를 잘못 이해했었다. requiredClasses의 배열의 요소들이 scores의 키에 있을 경우, 있는 요소들만 scores의 학점을 점수로 변환하고 없는 요소들에 대해서는 0점을 입히는 방식인줄 알았는데 그 반대였다. scores의 key에 대한 value는 모두 점수로 전환하고 requiredClasses의 요소에 대해서 key에 없는 경우 추가해서 0점을 입히면 되는 것이다. (괜히 배열의 이름이 requiredClasses가 아니었어..)

처음에는 scores의 학점을 점수로 변환하는 함수를 만들어서 getExamResult함수에 넣을려고 하였다.
하지만 잘 안되었다. 일단 함수 만드는것도 좀 어려웠고 점수를 변환해서 다시 object로 만드는 과정... 굉장히 오래걸렸다.
그러다 그냥 애초부터 과목당 숫자인 점수가 적혀있는 object를 만들면 이런 과정이 전혀 필요없다는 것을 깨달았다!!!!(이게 정말 컸다)
이렇게 할 경우 그냥 빈 object {}를 만들어서 채워주기만 하면 된다.(object는 key와 값의 추가 및 변경이 매우 쉽다.)
그 후 requiredClasses의 배열을 순회하고 위에 배웠던 scores의 키값을 Object.keys 를 이용하여 key의 배열로 만들면 includes를 이용할 수 있다.(includes의 결과는 boolean으로 나온다.)

그렇게 과제를 풀게 되었다. 푸는데 오래 걸렸지만 다양한 생각을 할 수 있어서 좋았다.

profile
열심히 살고 싶은 임채현입니다.

0개의 댓글