당신에게 item이라는 객체가 있습니다.
item 여러 property를 가지고 있고, 우린 이 property중에 조건에 맞는 것만 고른 새로운 객체 newItem을 만들어야 합니다.
예를들어 여러상태의 물체가 담겨있는 item이 있고, 그 중 액체인 것만 뽑아서 새로운 객체를 만든다고 해봅시다.
const liquids = ['water', 'oil']
const matter = {
water: ‘1L’,
oil: ‘2L’,
oxygen:’1mole’,
sand:’1t’
}
const filteredMatter = {}
자, filteredMatter를 만드는 코드를 짜봅시다.
첫 번째 시도입니다.
객체는 iterable하지 않기 때문에 순회를 돌 수 없습니다. 따라서, 다음과 같이 손수 꺼내주는 방법을 사용할 수 있겠네요.
// first trial
const filteredMatter = {};
liquids.forEach(liquid => {
filteredMatter[liquid] = matter[liquid];
})
console.log(filteredMatter);
이 코드는 정상적으로 동작합니다. 그러나 우아해 보이진 않습니다.
한 눈에 어떤 동작을 하는지 알아보기 힘들고, 외부 변수에 쓰기 동작을 하는것이 함수형 프로그래밍랍시고 forEach를 사용한 의미가 없다라는것을 알 수 있습니다.
이럴거면 그냥 for문을 사용하지 왜 forEach를 사용하나요 (forEach가 더 느림)
두 번째 시도입니다.
객체가 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를 사용해보길 권해봅니다.
이걸로 어제 삽질 많이 했는데...