Somebody asks you to loop through the properties of an object, most of us will reach for Object.keys right?
Object.keys(obj).forEach(key => { const value = obj[key]; // do something }) Somebody asks you to map the properties of an object to other values. Object.keys to the rescue again right?
const newObj = {}; Object.keys(obj).forEach(key => { newObj[key] = fn(obj[key]); }); Wait, no reduce? That's so 2018! Let's be needlessly functional:
const newObj = Object.keys(obj).reduce((acc, key) => { return { ...acc, [key]: fn(obj[key]) }, {}); Nice!
Thing is, Object.entries and Object.fromEntries are now widely supported. You can now achieve the same thing like this:
const newObj = Object.fromEntries( Object.entries(obj).map([key, value]) => { return [key, fn(value)]; }) ); It's also trivial to just make a utility function that combines the fromEntries and entries calls:
const mapEntries = (obj, fn) => Object.fromEntries( Object.entries(obj).map(fn) ); you could then write the above like this:
const newObj = mapEntries(obj, ([key, value]) => [key, fn(value)]); I love how simple this is, and you can do so much stuff that's always been a bit of a pain before.
Want to transform keys?
const newObj = mapEntries(obj, [key, value]) => [fn(key), value]); Want to invert an object?
const inverted = mapEntries(obj, ([key, value]) => [value, key]); Want to filter properties out of an object?
const filtered = Object.fromEntries( Object.entries(obj).filter(([ , value]) => { return value === true; }) ); Object.entries is awesome, have a play with it.
Top comments (0)