Add support for wildcards to u.updateIn

Fixes #27
This commit is contained in:
Aaron Jensen 2015-09-11 22:48:02 -07:00
parent 98a2037f8a
commit 2dfa674124
4 changed files with 51 additions and 2 deletions

View File

@ -1,6 +1,7 @@
# Change Log
## [unreleased]
* Add support for wildcards (`*`) to `u.updateIn`. (https://github.com/substantial/updeep/issues/27)
## [0.9.0]
* Do not add object during false branch of `u.if`.

View File

@ -186,7 +186,7 @@ expect(result).to.eql({ name: "Joe Merrill", age: 22 });
### `u.updateIn(path(, value)(, object))`
Update a single value with a simple string or array path. Can be use to update nested objects, arrays, or a combination.
Update a single value with a simple string or array path. Can be use to update nested objects, arrays, or a combination. Can also be used to update every element of a nested array with `'*'`.
```js
var result = u.updateIn('bunny.color', 'brown', { bunny: { color: 'black' } });
@ -214,6 +214,22 @@ var result = u({ pets: u.updateIn([0, 'bunny', 'age'], 3) }, { pets: [{ bunny: {
expect(result).to.eql({ pets: [{ bunny: { age: 3 } }] });
```
```js
var result = u.updateIn('todos.*.done', true, {
todos: [
{ done: false },
{ done: false },
]
});
expect(result).to.eql({
todos: [
{ done: true },
{ done: true },
]
});
```
### `u.constant(object)`
Sometimes, you want to replace an object outright rather than merging it.

View File

@ -1,10 +1,26 @@
import curry from './util/curry';
import update from './update';
import map from './map';
import splitPath from './util/splitPath';
const wildcard = '*';
function reducePath(acc, key) {
if (key === wildcard) {
return value =>
Object.prototype.hasOwnProperty.call(value, wildcard) ?
// If we actually have wildcard as a property, update that
update({ [wildcard]: acc }, value) :
// Otherwise map over all properties
map(acc, value);
}
return { [key]: acc };
}
function updateIn(path, value, object) {
const parts = splitPath(path);
const updates = parts.reduceRight((acc, key) => ({ [key]: acc }), value);
const updates = parts.reduceRight(reducePath, value);
return update(updates, object);
}

View File

@ -48,4 +48,20 @@ describe('u.updateIn', () => {
it('freezes the result', () => {
expect(Object.isFrozen(u.updateIn('a', 0, {}))).to.be.true;
});
it('can multiple elements of an array with *', () => {
let object = { a: [{ b: 0 }, { b: 1 }, { b: 2 }] };
let result = u.updateIn('a.*.b', x => x + 1, object);
expect(result).to.eql({ a: [{ b: 1 }, { b: 2 }, { b: 3 }] });
object = { a: [0, 1, 2] };
result = u.updateIn(['a', '*'], x => x + 1, object);
expect(result).to.eql({ a: [1, 2, 3] });
});
it('can update properties named *', () => {
const object = { '*': 1, x: 1 };
const result = u.updateIn('*', x => x + 1, object);
expect(result).to.eql({ '*': 2, x: 1 });
});
});