https://lodash.com/docs#mapKeys
Is it possible to map an Object's keys deeply using Lodash? If not, is there another library providing this functionality (if grouped with other deep iteration and manipulation functionality, even better!)? Else, how would one go about implementing this? The main struggle I see is in identifying pure key/value objects that are safely, deeply iterable. It's easy to throw out Arrays, but it's important to note that the function shouldn't try to deeply iterate on other objects like a regex, for example.
Intended result-
var obj = { a: 2, b: { c: 2, d: { a: 3 } } }; _.deepMapKeys(obj, function (val, key) { return key + '_hi'; }); // => { a_hi: 2, b_hi: { c_hi: 2, d_hi: { a_hi: 3 } } }
A key of an object must be a string or a symbol, you cannot use an object as a key. An object does not have a property that represents the size of the map.
The Lodash _. isEqual() Method performs a deep comparison between two values to determine if they are equivalent. This method supports comparing arrays, array buffers, boolean, date objects, maps, numbers, objects, regex, sets, strings, symbols, and typed arrays.
Lodash helps in working with arrays, collection, strings, objects, numbers etc. The _. map() method creates an array of values by running each element in collection through the iteratee. There are many lodash methods that are guarded to work as iteratees for methods like _.
In Lodash, we can deeply compare two objects using the _. isEqual() method. This method will compare both values to determine if they are equivalent.
Here's how you can do that in lodash
:
_.mixin({ 'deepMapKeys': function (obj, fn) { var x = {}; _.forOwn(obj, function(v, k) { if(_.isPlainObject(v)) v = _.deepMapKeys(v, fn); x[fn(v, k)] = v; }); return x; } });
and here's a more abstract mixin, that recursively applies any given mapper:
_.mixin({ deep: function (obj, mapper) { return mapper(_.mapValues(obj, function (v) { return _.isPlainObject(v) ? _.deep(v, mapper) : v; })); }, });
Usage (returns the same as above):
obj = _.deep(obj, function(x) { return _.mapKeys(x, function (val, key) { return key + '_hi'; }); });
Another option, with more elegant syntax:
_.mixin({ deeply: function (map) { return function(obj, fn) { return map(_.mapValues(obj, function (v) { return _.isPlainObject(v) ? _.deeply(map)(v, fn) : v; }), fn); } }, }); obj = _.deeply(_.mapKeys)(obj, function (val, key) { return key + '_hi'; });
In extention of georg's answer, here's what I'm using. This extended mixin adds the ability to map arrays of objects within the object too, a simple but important change.
_.mixin({ deeply: function (map) { return function (obj, fn) { return map(_.mapValues(obj, function (v) { return _.isPlainObject(v) ? _.deeply(map)(v, fn) : _.isArray(v) ? v.map(function(x) { return _.deeply(map)(x, fn); }) : v; }), fn); } }, });
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With