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)