Skip to content

Commit

Permalink
feature: adding paths operator - #2740 (#2742)
Browse files Browse the repository at this point in the history
* feature: adding paths operator - #2740

* refactor: making path a derivative of paths

* refactor: making props a derivative of path
  • Loading branch information
minaseem authored and CrossEye committed Feb 9, 2019
1 parent 235a370 commit efd899b
Show file tree
Hide file tree
Showing 5 changed files with 90 additions and 25 deletions.
1 change: 1 addition & 0 deletions source/index.js
Expand Up @@ -160,6 +160,7 @@ export { default as partial } from './partial';
export { default as partialRight } from './partialRight';
export { default as partition } from './partition';
export { default as path } from './path';
export { default as paths } from './paths';
export { default as pathEq } from './pathEq';
export { default as pathOr } from './pathOr';
export { default as pathSatisfies } from './pathSatisfies';
Expand Down
19 changes: 4 additions & 15 deletions source/path.js
@@ -1,6 +1,5 @@
import _curry2 from './internal/_curry2';
import _isInteger from './internal/_isInteger';
import nth from './nth';
import paths from './paths';

/**
* Retrieve the value at a given path.
Expand All @@ -22,18 +21,8 @@ import nth from './nth';
* R.path(['a', 'b', 0], {a: {b: [1, 2, 3]}}); //=> 1
* R.path(['a', 'b', -2], {a: {b: [1, 2, 3]}}); //=> 2
*/
var path = _curry2(function path(paths, obj) {
var val = obj;
var idx = 0;
var p;
while (idx < paths.length) {
if (val == null) {
return;
}
p = paths[idx];
val = _isInteger(p) ? nth(p, val) : val[p];
idx += 1;
}
return val;

var path = _curry2(function path(pathAr, obj) {
return paths([pathAr], obj)[0];
});
export default path;
38 changes: 38 additions & 0 deletions source/paths.js
@@ -0,0 +1,38 @@
import _curry2 from './internal/_curry2';
import _isInteger from './internal/_isInteger';
import nth from './nth';

/**
* Retrieves the values at given paths of an object.
*
* @func
* @memberOf R
* @category Object
* @typedefn Idx = [String | Int]
* @sig [Idx] -> {a} -> [a | Undefined]
* @param {Array} pathsArray The array of paths to be fetched.
* @param {Object} obj The object to retrieve the nested properties from.
* @return {Array} A list consisting of values at paths specified by "pathsArray".
* @see R.path
* @example
*
* R.paths([['a', 'b'], ['p', 0, 'q']], {a: {b: 2}, p: [{q: 3}]}); //=> [2, 3]
* R.paths([['a', 'b'], ['p', 'r']], {a: {b: 2}, p: [{q: 3}]}); //=> [2, undefined]
*/
var paths = _curry2(function paths(pathsArray, obj) {
return pathsArray.map(function(paths) {
var val = obj;
var idx = 0;
var p;
while (idx < paths.length) {
if (val == null) {
return;
}
p = paths[idx];
val = _isInteger(p) ? nth(p, val) : val[p];
idx += 1;
}
return val;
});
});
export default paths;
14 changes: 4 additions & 10 deletions source/props.js
@@ -1,4 +1,5 @@
import _curry2 from './internal/_curry2';
import path from './path';


/**
Expand All @@ -22,15 +23,8 @@ import _curry2 from './internal/_curry2';
* fullName({last: 'Bullet-Tooth', age: 33, first: 'Tony'}); //=> 'Tony Bullet-Tooth'
*/
var props = _curry2(function props(ps, obj) {
var len = ps.length;
var out = [];
var idx = 0;

while (idx < len) {
out[idx] = obj[ps[idx]];
idx += 1;
}

return out;
return ps.map(function(p) {
return path([p], obj);
});
});
export default props;
43 changes: 43 additions & 0 deletions test/paths.js
@@ -0,0 +1,43 @@
var R = require('../source');
var eq = require('./shared/eq');

describe('paths', function() {
var obj = {
a: {
b: {
c: 1,
d: 2
}
},
p: [{q: 3}, 'Hi'],
x: {
y: 'Alice',
z: [[{}]]
}
};
it('takes paths and returns values at those paths', function() {
eq(R.paths([['a', 'b', 'c'], ['x', 'y']], obj), [1, 'Alice']);
eq(R.paths([['a', 'b', 'd'], ['p', 'q']], obj), [2, undefined]);
});

it('takes a paths that contains indices into arrays', function() {
eq(R.paths([['p', 0, 'q'], ['x', 'z', 0, 0]], obj), [3, {}]);
eq(R.paths([['p', 0, 'q'], ['x', 'z', 2, 1]], obj), [3, undefined]);
});

it('takes a path that contains negative indices into arrays', function() {
eq(R.paths([['p', -2, 'q'], ['p', -1]], obj), [3, 'Hi']);
eq(R.paths([['p', -4, 'q'], ['x', 'z', -1, 0]], obj), [undefined, {}]);
});

it("gets a deep property's value from objects", function() {
eq(R.paths([['a', 'b']], obj), [obj.a.b]);
eq(R.paths([['p', 0]], obj), [obj.p[0]]);
});

it('returns undefined for items not found', function() {
eq(R.paths([['a', 'x', 'y']], obj), [undefined]);
eq(R.paths([['p', 2]], obj), [undefined]);
});

});

0 comments on commit efd899b

Please sign in to comment.