[Wecode] 2022-09-23

김택수·2022년 9월 23일
0

object

객체의 키를 변수로 접근하기

결론적으로 객체의 키를 변수로 접근하게 되면, 고정된 값이 아닌 변수 안의 내용이 바뀔때마다 유동적으로 바꿀 수 있기 때문이며, 유용하게 사용되기 때문에 사용법을 알아놓을 필요가 있다.

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

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

// 키를 변수로 접근하기
information[verb] = project

const information = {
	name: '김개발',
  	developes: 'facebook'
}

객체 순회하기

객체는 순서가 없어서 키를 통해서만 접근이 가능한데, 몇가지 방법을 통해서 객체도 배열처럼 요소들을 순회할 수 있다. 다만, 명확하게 정해진 순서가 없기 때문에 어떤 순서에 따라서 접근하는지는 보장받을 수 없다. 때문에 객체의 순회는 순서가 보장되지 않은 순회라고 부른다.

Object.keys()

특정 객체가 가지고 있는 키들의 목록을 배열로 리턴하는 메소드. 객체에 사용하는 것이 아닌 Object 생성자를 통해 사용할 수 있다. 후에 리턴된 배열로 for문을 돌려 객체를 순회할 수 있다.

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(i = 0; i < keys.length; i++) {
	const key = keys[i]; // 각각의 키에 먼저 접근
    const value = obj[key] // 각각의 키의 해당하는 value를 반환
    console.log(value) // 모든 키에 대한 value를 반환
}

Object.entires()

객체의 키와 값이 한 쌍으로 이루어진 길이 2짜리 배열로 이루어진 배열을 리턴한다. 인덱스 [0]은 키값을, 인덱스 [1]은 키 값에 대한 value값을 가진다.

const entries = Object.entries(obj)
// [['name', 'melon'], ['weight', 4350], ['price', 16500], ['isFresh', true]]

for-in문

객체와 배열을 위해 특별히 존재하는 for문의 종류이며, 객체 순회 외에도 일반적인 배열을 순회할때도 유용할 수 있다.

for (i = 0; i<arr.length; i++) // 일반적인 for문에서 자주 쓰이는 문법
for (i in arr) // 위의 문법과 같이 i를 0으로 초기화하고 arr의 length만큼 돌며 i를 1씩 더해준다는 문법

해당 문법은 객체 순회에도 사용가능하다고 설명했는데 방법은 하단과 같다.

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

for(key in obj) {
	const value = obj[key] // obj내의 key값에 대한 value를 반환
    
    console.log(key)
  	console.log(value)
}

문제 풀이

영어로 되어있는 점수를 숫자로 변환하고, 두번째 인자로 주어지는 배열안의 내용과 첫번째 인자로 받는 객체의 키값을 비교하여 객체의 키값에는 존재하지 않지만 배열안에는 존재하는 과목을 객체 안에 추가하고, 점수를 F로 통일해서 부여하는 문제

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

  // 숫자로 점수 변환
  for(key in scores) {
    newScores[key] = grade[scores[key]];
  }

  // 변환한 객체를 배열로 변환
  const scoreArr = Object.keys(newScores);
  
  for(i in requiredClasses) {
    if(scoreArr.includes(requiredClasses[i]) === false) {
      newScores[[requiredClasses[i]]] = 0;
    }
  }
  return newScores;
}

풀이 중 오류상황 및 풀이방법

1) 객체를 배열로 변환하고, 배열 간 요소를 비교해야한다는 것까지는 유추가 가능했으나, 배열 간 길이가 다르기 때문에 하나의 for문으로는 모든 요소를 비교할 수 없다는 결론에 닿았음.

2) for문 중첩 시, 지속적으로 코드가 꼬여서 길을 잃어가던 도중, map메서드를 통해 모든 요소에 두번째 인자로 받는 배열만큼의 반복문을 사용해 비교하는 방법을 사용했으나, 각 요소에 접근하기가 용이하지 않았음.

3) 하루종일 고민하던 끝에, 배열 간 요소를 비교해주는 includes메서드라는 것을 알 수 있었다.

4) 첫번째로 첫번째 인자로 받는 scores를 순회하는 for-in문을 선언하고, return할 객체의 key값의 value값을 grade의 키 값 중 scores의 key값과 맞는 value값을 반환할 수 있도록 접근했다.

for(key in scores) {
    newScores[key] = grade[scores[key]];
  }

5) 후에, 점수를 변환한 객체(newScores)를 배열로 변환하는 keys메서드를 사용했다.

const scoreArr = Object.keys(newScores);

6) for문을 두번째 인자인 requiredClasses(배열)의 길이만큼 돌리고, 배열로 변환한 scoreArr 요소 중 requiredClasses의 요소와 같은지 확인 할 수 있는 includes메서드를 사용해서 값이 false일 경우(scoreArr에 값이 존재하지 않을 경우)에 반환할 newScores의 key값을 includes에서 false로 나온(값이 존재하지 않는) 값을 key값으로 주고, 그 key값에 대한 점수는 0으로 주는 방식으로 해결

 for(i in requiredClasses) {
    if(scoreArr.includes(requiredClasses[i]) === false) {
      newScores[[requiredClasses[i]]] = 0;
    }
  }

※ 풀이 중 가장 어려웠던 풀이로 너무 많은 요소들을 건드려고 하면 코드가 지저분해지고 로직이 단순해 지지 않는 것을 느꼈음. 처음에 내가 풀이하려 했던 방식은 모든 요소를 내가 다 가지고 있고, 그 요소들을 끼워맞추는 식이 되다보니 풀기가 난해했는데, 나중에 생각해낸 로직들은 최대한 간단하게 변환하고 확인하고 원래 있는 것을 많이 건들지 않는 식으로 진행했고, 이렇게 진행하니 코드도 깔끔해지고, 흐름들을 빠르게 파악할 수 있어 좋았다.

※ 또한, includes메서드를 몰라 많은 시행착오를 겪은 것에 많이 허탈했던 문제, 모든 메서드를 외워서 사용할 필요는 없지만, 최소한 배열 간 요소를 비교하는 검색정도를 해봤다면 충분히 금방 알아낼 수 있었던 메서드 였다. 조금 더 똑똑하게 문제를 해결하는 방법을 고민해보는 것도 좋은 방법일 것 같다.

profile
개발자 키우기 Lv1

0개의 댓글