[JS] 객체는 iterable하지 않다

GuruneLee·2022년 6월 8일
0

Let's Study 공부해요~

목록 보기
16/36

문제 상황

당신에게 item이라는 객체가 있습니다.
item 여러 property를 가지고 있고, 우린 이 property중에 조건에 맞는 것만 고른 새로운 객체 newItem을 만들어야 합니다.

예를들어 여러상태의 물체가 담겨있는 item이 있고, 그 중 액체인 것만 뽑아서 새로운 객체를 만든다고 해봅시다.

const liquids = ['water', 'oil']

const matter = {
	water:1L’, 
    oil:2L’, 
    oxygen:1mole’, 
	sand:1t’
}
const filteredMatter = {}

자, filteredMatter를 만드는 코드를 짜봅시다.

두 가지 해결방안

First

첫 번째 시도입니다.
객체는 iterable하지 않기 때문에 순회를 돌 수 없습니다. 따라서, 다음과 같이 손수 꺼내주는 방법을 사용할 수 있겠네요.

// first trial
const filteredMatter = {};
liquids.forEach(liquid => {
  filteredMatter[liquid] = matter[liquid];
})
console.log(filteredMatter);

이 코드는 정상적으로 동작합니다. 그러나 우아해 보이진 않습니다.
한 눈에 어떤 동작을 하는지 알아보기 힘들고, 외부 변수에 쓰기 동작을 하는것이 함수형 프로그래밍랍시고 forEach를 사용한 의미가 없다라는것을 알 수 있습니다.

이럴거면 그냥 for문을 사용하지 왜 forEach를 사용하나요 (forEach가 더 느림)

Second

두 번째 시도입니다.
객체가 iterable하지 않다면, iterable하게 만들어주면 됩니다. 다음 코드를 봅시다.

// second trial
const filtered = Object.entries(matter)
	.filter(entry=>fluid.includes(entry[0]))
const filteredMatter = Object.fromEntries(filtered);

객체는 iterable 하지 않지만, Object.entries라는 메서드의 반환값은 iterable하다는 것을 알 수 있습니다. Object.entries와 Object.fromEntires의 역할이 크네요!

1) Object.etries(obj)
: 인자로 들어온 객체를 무려 배열로 만들어주는 메서드입니다.
객체의 key-value 쌍들을 다음과 같이 이차원 배열로 펴주는 역할입니다 (객체가 아닌 다른 자료형 인자에 대해선 MDN를 참고하자)

const obj = { key1: val1, ... keyN: valN }
const array = Object.entries(obj) // [[key1, val1], ... [keyN, valN]]

2) Object.fromEntries(ent)
: key-value 페어로 이루어진 이차원 배열을 객체로 만들어주는 메서드입니다.

const keyValue = [[key1, val1], ... [keyN, valN]]
const obj = Object.fromEntries(keyValue) // { key1: val1, ... keyN: valN }

Array가 아닌 Map을 인자로넘기는 것도 가능합니다. 마찬가지로 MDN을 참고합시다

마무리

객체를 iterable한 배열로 만들어서 순회하는 방법을 알아보았습니다.
사실 이 외에도, Object.keys를 이용해 key배열을 순회시키는 방법도 있고, 뭐 여러 방법이 있을 것입니다 (Object.values도 있군요).

하지만, 위의 문제상황과 같이 객체의 key-value를 모두 반환해야 하는 상황이라면 Object.entries를 사용해보길 권해봅니다.

이걸로 어제 삽질 많이 했는데...

profile
Today, I Shoveled AGAIN....

0개의 댓글