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';
2015-08-05 07:27:56 +00:00
function resolveUpdates(updates, object = {}) {
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-05 07:27:56 +00:00
updatedValue = update(value, object[key]);
} else if (typeof value === 'function') {
2015-08-05 07:27:56 +00:00
updatedValue = value(object[key]);
}
2015-08-05 07:27:56 +00:00
if (object[key] !== updatedValue) {
2015-08-02 06:25:08 +00:00
acc[key] = updatedValue;
}
return acc;
}, {});
}
2015-08-05 07:27:56 +00:00
function updateArray(updates, object) {
const newObj = [...object];
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
*/
2015-08-05 07:27:56 +00:00
function update(updates, object) {
if (typeof updates === 'function') {
2015-08-05 07:27:56 +00:00
return updates(object);
}
2015-08-05 07:27:56 +00:00
const resolvedUpdates = resolveUpdates(updates, object);
if (isEmpty(resolvedUpdates)) {
2015-08-05 07:27:56 +00:00
return object;
}
2015-08-05 07:27:56 +00:00
if (Array.isArray(object)) {
return updateArray(resolvedUpdates, object);
}
2015-08-05 07:27:56 +00:00
return assign({}, object, resolvedUpdates);
}
2015-08-02 07:32:32 +00:00
export default update;