const fruits = {
apple: 2,
orange: 3,
grape: 4,
banana: 5
}
I would like to modify some of the values of fruits where I also have access to its current value.
Something like this
const premiumFrutis = _.doSomething(fruits, apple + 2, banana + 3)
// premiumFrutis = {
// apple: 4,
// orange: 3,
// grape: 4,
// banana: 8
// }
This is the job of _.assignWith
or _.assignInWith
. The difference is that assignIn
will go through the prototype chain but when dealing with plain objects, then both will work the same.
In both cases, a customiser option can be provided which will be used when the values of the objects are combined. A simple implementation is
const combineValues = (srcValue, objValue) =>
srcValue + objValue;
which will sum values for the same key:
const fruits = {
apple: 2,
orange: 3,
grape: 4,
banana: 5
}
const combineValues = (srcValue, objValue) =>
srcValue + objValue;
const modification = {apple: 2, banana: 3};
const premiumFrutis = _.assignWith(fruits, modification, combineValues);
console.log(premiumFrutis);
// {
// apple: 4,
// orange: 3,
// grape: 4,
// banana: 8
// }
<script src="https://cdn.jsdelivr.net/npm/[email protected]/lodash.min.js"></script>
However, it is not even needed to implement this, since Lodash already provides _.add
and it can be directly used:
const fruits = {
apple: 2,
orange: 3,
grape: 4,
banana: 5
}
const modification = {apple: 2, banana: 3};
const premiumFrutis = _.assignWith(fruits, modification, _.add);
console.log(premiumFrutis);
// {
// apple: 4,
// orange: 3,
// grape: 4,
// banana: 8
// }
<script src="https://cdn.jsdelivr.net/npm/[email protected]/lodash.min.js"></script>
This will also do subtraction if you pass negative values:
const fruits = {
apple: 2,
orange: 3,
grape: 4,
banana: 5
}
const modification = {apple: 2, banana: -1};
const premiumFrutis = _.assignWith(fruits, modification, _.add);
console.log(premiumFrutis);
// {
// apple: 4,
// orange: 3,
// grape: 4,
// banana: 4
// }
<script src="https://cdn.jsdelivr.net/npm/[email protected]/lodash.min.js"></script>
The only potential problem is more modifications need to be passed than there are keys in the original objects:
const fruits = {
apple: 2,
orange: 3,
grape: 4,
banana: 5
}
const modification = {apple: 2, banana: 3, lemon: 42};
const premiumFrutis = _.assignWith(fruits, modification, _.add);
console.log(premiumFrutis);
// {
// apple: 4,
// orange: 3,
// grape: 4,
// banana: 8,
// lemon: 42
// }
<script src="https://cdn.jsdelivr.net/npm/[email protected]/lodash.min.js"></script>
If no new items should be added, then _.pickBy
can be used to remove any modifications that are not in the initial object:
const fruits = {
apple: 2,
orange: 3,
grape: 4,
banana: 5
}
const modification = {apple: 2, banana: 3, lemon: 42};
const onlyExisting = _.pickBy(modification, (value, key) => key in fruits);
const premiumFrutis = _.assignWith(fruits, onlyExisting, _.add);
console.log(premiumFrutis);
// {
// apple: 4,
// orange: 3,
// grape: 4,
// banana: 8
// }
<script src="https://cdn.jsdelivr.net/npm/[email protected]/lodash.min.js"></script>