Add u.is
This commit is contained in:
parent
59ec770a88
commit
5c0855b9df
@ -1,9 +1,10 @@
|
|||||||
# Change Log
|
# Change Log
|
||||||
|
|
||||||
## [unreleased]
|
## [unreleased]
|
||||||
|
* Add `u.is` to test predicates in a single path. (https://github.com/substantial/updeep/issues/13)
|
||||||
|
|
||||||
## [0.4.0]
|
## [0.4.0]
|
||||||
* Add `u.if` and `u.ifElse` to conditionally update objects.
|
* Add `u.if` and `u.ifElse` to conditionally update objects. (https://github.com/substantial/updeep/issues/12)
|
||||||
* Add `u.map` to update all values in an array or object.
|
* Add `u.map` to update all values in an array or object.
|
||||||
* Replace object outright if null or constant provided as `updates`.
|
* Replace object outright if null or constant provided as `updates`.
|
||||||
* Freeze objects returned by helper methods that use `update` like `withDefault`, `map`, `in`, etc. Previously, only `u` did freezing.
|
* Freeze objects returned by helper methods that use `update` like `withDefault`, `map`, `in`, etc. Previously, only `u` did freezing.
|
||||||
|
27
README.md
27
README.md
@ -219,8 +219,8 @@ u({ x: u.omit(['b', 'c']) }, { x: { a: 0, b: 0, c: 0 } });
|
|||||||
Reject items from an array. See [`_.reject`](https://lodash.com/docs#reject).
|
Reject items from an array. See [`_.reject`](https://lodash.com/docs#reject).
|
||||||
|
|
||||||
```js
|
```js
|
||||||
function even(i) { return i % 2 === 0 };
|
function isEven(i) { return i % 2 === 0; }
|
||||||
u({ x: u.reject(even) }, { x: [1, 2, 3, 4] });
|
u({ x: u.reject(isEven) }, { x: [1, 2, 3, 4] });
|
||||||
// => { x: [1, 3] }
|
// => { x: [1, 3] }
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -235,6 +235,29 @@ u({ x: u.withDefault([], { 0: 3 }) }, {});
|
|||||||
|
|
||||||
See the [tests] for more examples.
|
See the [tests] for more examples.
|
||||||
|
|
||||||
|
### `u.is(path(, predicate)(, object))`
|
||||||
|
|
||||||
|
Returns `true` if the `predicate` matches the `path` applied to the `object`.
|
||||||
|
If the `predicate` is a function, the result is returned. If not, they are compared with `===`.
|
||||||
|
|
||||||
|
```js
|
||||||
|
u.is('a.b', 4, { a: { b: 4 } });
|
||||||
|
// => true
|
||||||
|
```
|
||||||
|
|
||||||
|
```js
|
||||||
|
function isEven(i) { return i % 2 === 0; }
|
||||||
|
u.is('a.b', isEven, { a: { b: 4 } });
|
||||||
|
// => true
|
||||||
|
```
|
||||||
|
|
||||||
|
```js
|
||||||
|
u({
|
||||||
|
person: u.if(u.is('name.first', 'Jen'), u.in('name.last', 'Simpson'))
|
||||||
|
}, { person: { name: { first: 'Jen', last: 'Matthews' } } });
|
||||||
|
// => { person: { name: { first: 'Jen', last: 'Simpson' } } }
|
||||||
|
```
|
||||||
|
|
||||||
## Install
|
## Install
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
|
@ -1,12 +1,9 @@
|
|||||||
import curry from 'lodash/function/curry';
|
import curry from 'lodash/function/curry';
|
||||||
import reject from 'lodash/collection/reject';
|
|
||||||
import update from './update';
|
import update from './update';
|
||||||
|
import splitPath from './util/splitPath';
|
||||||
|
|
||||||
function updateIn(path, value, object) {
|
function updateIn(path, value, object) {
|
||||||
const parts = Array.isArray(path) ?
|
const parts = splitPath(path);
|
||||||
path :
|
|
||||||
reject(path.split('.'), x => !x);
|
|
||||||
|
|
||||||
const updates = parts.reduceRight((acc, key) => ({ [key]: acc }), value);
|
const updates = parts.reduceRight((acc, key) => ({ [key]: acc }), value);
|
||||||
|
|
||||||
return update(updates, object);
|
return update(updates, object);
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import freeze from './freeze';
|
import freeze from './freeze';
|
||||||
import _in from './in';
|
import _in from './in';
|
||||||
|
import is from './is';
|
||||||
import ifElse from './ifElse';
|
import ifElse from './ifElse';
|
||||||
import map from './map';
|
import map from './map';
|
||||||
import omit from './omit';
|
import omit from './omit';
|
||||||
@ -14,6 +15,7 @@ const u = update;
|
|||||||
u.if = ifElse(_, _, {});
|
u.if = ifElse(_, _, {});
|
||||||
u.ifElse = ifElse;
|
u.ifElse = ifElse;
|
||||||
u.in = _in;
|
u.in = _in;
|
||||||
|
u.is = is;
|
||||||
u.freeze = freeze;
|
u.freeze = freeze;
|
||||||
u.map = map;
|
u.map = map;
|
||||||
u.omit = omit;
|
u.omit = omit;
|
||||||
|
21
lib/is.js
Normal file
21
lib/is.js
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
import splitPath from './util/splitPath';
|
||||||
|
import curry from 'lodash/function/curry';
|
||||||
|
|
||||||
|
function is(path, predicate, object) {
|
||||||
|
const parts = splitPath(path);
|
||||||
|
|
||||||
|
let rest = object;
|
||||||
|
let part;
|
||||||
|
for (part of parts) {
|
||||||
|
if (typeof rest === 'undefined') return false;
|
||||||
|
rest = rest[part];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof predicate === 'function') {
|
||||||
|
return predicate(rest);
|
||||||
|
}
|
||||||
|
|
||||||
|
return predicate === rest;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default curry(is);
|
7
lib/util/splitPath.js
Normal file
7
lib/util/splitPath.js
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
import reject from 'lodash/collection/reject';
|
||||||
|
|
||||||
|
export default function splitPath(path) {
|
||||||
|
return Array.isArray(path) ?
|
||||||
|
path :
|
||||||
|
reject(path.split('.'), x => !x);
|
||||||
|
}
|
59
test/is-spec.js
Normal file
59
test/is-spec.js
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
import { expect } from 'chai';
|
||||||
|
import u from '../lib';
|
||||||
|
|
||||||
|
describe('u.is', () => {
|
||||||
|
it('returns true if path matches a value predicate', () => {
|
||||||
|
const result = u.is('a.b', 4, { a: { b: 4 } });
|
||||||
|
expect(result).to.be.true;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns true if path matches a function predicate', () => {
|
||||||
|
const isEven = x => x % 2 === 0;
|
||||||
|
const result = u.is('a.b', isEven, { a: { b: 6 } });
|
||||||
|
expect(result).to.be.true;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns false if path matches a value predicate', () => {
|
||||||
|
const result = u.is('a.b', 4, { a: { b: 5 } });
|
||||||
|
expect(result).to.be.false;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns false if path matches a function predicate', () => {
|
||||||
|
const isEven = x => x % 2 === 0;
|
||||||
|
const result = u.is('a.b', isEven, { a: { b: 7 } });
|
||||||
|
expect(result).to.be.false;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns false if the path does not exist', () => {
|
||||||
|
const result = u.is('a.b.c.d', 4, { a: { b: {} } });
|
||||||
|
expect(result).to.be.false;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('can test for undefined', () => {
|
||||||
|
const result = u.is('a.b.c', undefined, { a: { b: {} } });
|
||||||
|
expect(result).to.be.true;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('tests the actual object if a blank path is given', () => {
|
||||||
|
const result = u.is('', 4, 4);
|
||||||
|
expect(result).to.be.true;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('can use arrays as paths', () => {
|
||||||
|
const result = u.is(['a', 'b'], 4, { a: { b: 4 } });
|
||||||
|
expect(result).to.be.true;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('can include array indexes in paths', () => {
|
||||||
|
let result = u.is('a.1.b', 4, { a: [{}, { b: 4 }] });
|
||||||
|
expect(result).to.be.true;
|
||||||
|
|
||||||
|
result = u.is(['a', 1, 'b'], 4, { a: [{}, { b: 4 }] });
|
||||||
|
expect(result).to.be.true;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('can be partially applied', () => {
|
||||||
|
const result = u.is('a.b')(4)({ a: { b: 4 } });
|
||||||
|
expect(result).to.be.true;
|
||||||
|
});
|
||||||
|
});
|
Loading…
Reference in New Issue
Block a user