updeep-remeda/lib/update.js

65 lines
1.5 KiB
JavaScript
Raw Normal View History

2015-08-01 15:13:25 +00:00
import reduce from 'lodash/collection/reduce';
import isEmpty from 'lodash/lang/isEmpty';
2015-08-01 16:09:52 +00:00
import assign from 'lodash/object/assign';
function resolveUpdates(updates, obj = {}) {
return reduce(updates, (acc, value, key) => {
2015-08-02 06:25:08 +00:00
let updatedValue = value;
2015-08-05 04:33:27 +00:00
if (!Array.isArray(value) && value !== null && typeof value === 'object') {
2015-08-02 06:25:08 +00:00
updatedValue = update(value, obj[key]);
} else if (typeof value === 'function') {
2015-08-02 06:25:08 +00:00
updatedValue = value(obj[key]);
}
2015-08-02 06:25:08 +00:00
if (obj[key] !== updatedValue) {
acc[key] = updatedValue;
}
return acc;
}, {});
}
function updateArray(updates, obj) {
const newObj = [...obj];
return reduce(updates, (acc, value, index) => {
acc[index] = value;
return acc;
}, newObj);
}
/**
* Recursively update an object or array.
*
* Can update with values:
* update({ foo: 3 }, { foo: 1, bar: 2 });
* // => { foo: 3, bar: 2 }
*
* Or with a function:
* update({ foo: x => (x + 1) }, { foo: 2 });
* // => { foo: 3 }
2015-08-02 06:38:27 +00:00
*
* @param {Object|Function} updates
* @param {Object|Array} object to update
* @return {Object|Array} new object with modifications
*/
function update(updates, obj) {
if (typeof updates === 'function') {
return updates(obj);
}
const resolvedUpdates = resolveUpdates(updates, obj);
if (isEmpty(resolvedUpdates)) {
return obj;
}
if (Array.isArray(obj)) {
return updateArray(resolvedUpdates, obj);
}
2015-08-01 16:09:52 +00:00
return assign({}, obj, resolvedUpdates);
}
2015-08-02 07:32:32 +00:00
export default update;