Comparing version 1.5.5 to 1.6.0
218
deepdash.js
'use strict'; | ||
(function() { | ||
@@ -22,8 +21,12 @@ function apply(_) { | ||
} | ||
if(!_.isObject(obj)) | ||
return; | ||
if (!_.isObject(obj)) return; | ||
_.forOwn(obj, function(value, key) { | ||
var okey = key; | ||
if (_.isArray(obj)) key = '[' + key + ']'; | ||
else { | ||
if (_.isArray(obj)) { | ||
if (value === undefined && !(value in obj)) { | ||
//empty slot | ||
return; | ||
} | ||
key = '[' + key + ']'; | ||
} else { | ||
if (_.isString(key) && key.match(/^[a-zA-Z_$]+([\w_$]*)$/)) | ||
@@ -64,4 +67,4 @@ key = '.' + key; | ||
if (!_.eachDeep||!_.forEachDeep) { | ||
function eachDeep(obj, callback, options) { | ||
if (!_.eachDeep || !_.forEachDeep) { | ||
var eachDeep = function(obj, callback, options) { | ||
if (callback === undefined) callback = _.identity; | ||
@@ -79,4 +82,4 @@ options = _.merge( | ||
return obj; | ||
} | ||
if(!_.eachDeep){ | ||
}; | ||
if (!_.eachDeep) { | ||
_.mixin({ eachDeep: eachDeep }); | ||
@@ -88,4 +91,4 @@ } | ||
} | ||
if(!_.indexate){ | ||
function indexate(obj, options) { | ||
if (!_.indexate) { | ||
var indexate = function(obj, options) { | ||
options = _.merge( | ||
@@ -95,3 +98,3 @@ { | ||
includeCircularPath: true, | ||
leafsOnly:false | ||
leafsOnly: true, | ||
}, | ||
@@ -118,11 +121,11 @@ options || {} | ||
if (options.checkCircular) { | ||
circular =_.indexOf(parents.values, value) !== -1; | ||
circular = _.indexOf(parents.values, value) !== -1; | ||
} | ||
if(!circular||options.includeCircularPath){ | ||
if(options.leafsOnly && res[parentPath]){ | ||
if (!circular || options.includeCircularPath) { | ||
if (options.leafsOnly && res[parentPath]) { | ||
delete res[parentPath]; | ||
} | ||
res[path]=value; | ||
res[path] = value; | ||
} | ||
if(circular){ | ||
if (circular) { | ||
return false; | ||
@@ -134,9 +137,7 @@ } | ||
return res; | ||
} | ||
if(!_.indexate){ | ||
_.mixin({ indexate: indexate }); | ||
} | ||
}; | ||
_.mixin({ indexate: indexate }); | ||
} | ||
if (!_.keysDeep||!_.paths) { | ||
function paths(obj, options) { | ||
if (!_.keysDeep || !_.paths) { | ||
var paths = function(obj, options) { | ||
options = _.merge( | ||
@@ -146,3 +147,3 @@ { | ||
includeCircularPath: true, | ||
leafsOnly:false | ||
leafsOnly: true, | ||
}, | ||
@@ -169,6 +170,6 @@ options || {} | ||
if (options.checkCircular) { | ||
circular =_.indexOf(parents.values, value) !== -1; | ||
circular = _.indexOf(parents.values, value) !== -1; | ||
} | ||
if(!circular||options.includeCircularPath){ | ||
if(options.leafsOnly && _.last(res)===parentPath){ | ||
if (!circular || options.includeCircularPath) { | ||
if (options.leafsOnly && _.last(res) === parentPath) { | ||
res.pop(); | ||
@@ -178,3 +179,3 @@ } | ||
} | ||
if(circular){ | ||
if (circular) { | ||
return false; | ||
@@ -186,4 +187,4 @@ } | ||
return res; | ||
} | ||
if(!_.keysDeep){ | ||
}; | ||
if (!_.keysDeep) { | ||
_.mixin({ keysDeep: paths }); | ||
@@ -195,10 +196,161 @@ } | ||
} | ||
if (!_.condense) { | ||
_.mixin({ | ||
condense: function(arr) { | ||
_.remove(arr, function(val, key, coll) { | ||
return !(key in coll); | ||
}); | ||
return arr; | ||
}, | ||
}); | ||
} | ||
if (!_.condenseDeep) { | ||
var condenseDeep = function(obj, options) { | ||
options = _.merge( | ||
{ | ||
checkCircular: false, | ||
}, | ||
options || {} | ||
); | ||
var eachDeepOptions = { | ||
track: options.checkCircular, | ||
}; | ||
var arrays = []; | ||
_.eachDeep( | ||
obj, | ||
function( | ||
value, | ||
key, | ||
path, | ||
depth, | ||
parent, | ||
parentKey, | ||
parentPath, | ||
parents | ||
) { | ||
if ( | ||
options.checkCircular && | ||
_.indexOf(parents.values, value) !== -1 | ||
) { | ||
return false; | ||
} | ||
if (_.isArray(value)) arrays.push(value); | ||
}, | ||
eachDeepOptions | ||
); | ||
if (_.isArray(obj)) arrays.push(obj); | ||
_.each(arrays, _.condense); | ||
return obj; | ||
}; | ||
_.mixin({ | ||
condenseDeep: condenseDeep, | ||
}); | ||
} | ||
if (!_.filterDeep) { | ||
var filterDeep = function(obj, predicate, options) { | ||
options = _.merge( | ||
{ | ||
checkCircular: false, | ||
keepCircular: true, | ||
//replaceCircularBy: <by>, | ||
leafsOnly: true, | ||
condense: true, | ||
cloneDeep: _.cloneDeep, | ||
}, | ||
options || {} | ||
); | ||
var eachDeepOptions = { | ||
track: options.checkCircular, | ||
}; | ||
var res = _.isArray(obj) ? [] : {}; | ||
var foundCircular = []; | ||
var checkCircular = function(value, path, parents) { | ||
if (!options.checkCircular) return false; | ||
var i = _.indexOf(parents.values, value); | ||
if (i !== -1) { | ||
if (options.keepCircular) { | ||
foundCircular.push([path, parents.paths[i]]); | ||
} | ||
return true; | ||
} | ||
return false; | ||
}; | ||
// console.log('filterDeep', obj); | ||
_.eachDeep( | ||
obj, | ||
function( | ||
value, | ||
key, | ||
path, | ||
depth, | ||
parent, | ||
parentKey, | ||
parentPath, | ||
parents | ||
) { | ||
var circular = false; | ||
var isLeaf = !_.isObject(value) || _.isEmpty(value); | ||
if (!isLeaf) { | ||
circular = checkCircular(value, path, parents); | ||
} | ||
// console.log('filter each, l:' + isLeaf + ', c:' + circular, path); | ||
if (!circular) { | ||
if (isLeaf || !options.leafsOnly) { | ||
var condition = predicate( | ||
value, | ||
key, | ||
path, | ||
depth, | ||
parent, | ||
parentKey, | ||
parentPath, | ||
parents | ||
); | ||
if (condition === true) { | ||
_.set(res, path, options.cloneDeep(value)); | ||
} | ||
return condition; | ||
} | ||
} else { | ||
return false; | ||
} | ||
}, | ||
eachDeepOptions | ||
); | ||
_.each(foundCircular, function(c) { | ||
var cv; | ||
var has = c[1] == '' || _.has(res, c[1]); | ||
if (!has) return; | ||
if (_.has(options, 'replaceCircularBy')) { | ||
cv = options.replaceCircularBy; | ||
} else if (c[1] == '') { | ||
cv = res; | ||
} else { | ||
cv = _.get(res, c[1]); | ||
} | ||
_.set(res, c[0], cv); | ||
}); | ||
if (options.condense) | ||
return _.condenseDeep(res, { checkCircular: options.checkCircular }); | ||
return res; | ||
}; | ||
_.mixin({ filterDeep: filterDeep }); | ||
} | ||
return _; | ||
} | ||
if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') | ||
if ( | ||
typeof module !== 'undefined' && | ||
typeof module.exports !== 'undefined' && | ||
!process.env.likebrowser | ||
) { | ||
module.exports = apply; | ||
else if (_) apply(_); | ||
else throw new Error('No lodash to patch'); | ||
} else { | ||
if (typeof _ !== 'undefined') { | ||
apply(_); | ||
} else throw new Error('No lodash to mixin'); | ||
} | ||
})(); |
{ | ||
"name": "deepdash", | ||
"version": "1.5.5", | ||
"version": "1.6.0", | ||
"description": "Object tree traversal for lodash", | ||
@@ -23,2 +23,3 @@ "main": "deepdash.js", | ||
"each deep", | ||
"filter deep", | ||
"keys deep", | ||
@@ -30,2 +31,3 @@ "object", | ||
"forEachDeep", | ||
"filterDeep", | ||
"keysDeep", | ||
@@ -44,6 +46,9 @@ "paths" | ||
"coveralls": "^3.0.2", | ||
"eslint": "^5.8.0", | ||
"eslint": "^5.10.0", | ||
"eslint-config-prettier": "^3.3.0", | ||
"eslint-plugin-prettier": "^3.0.0", | ||
"mocha": "^5.2.0", | ||
"nodemon": "^1.18.8", | ||
"nyc": "^13.1.0" | ||
"nodemon": "^1.18.9", | ||
"nyc": "^13.1.0", | ||
"prettier": "^1.15.3" | ||
}, | ||
@@ -50,0 +55,0 @@ "dependencies": { |
187
README.md
<img src="deepdash.svg?sanitize=true" width="64px"/> | ||
## deepdash | ||
Looking for eachDeep, keysDeep etc? Tree traversal extension for lodash. | ||
Looking for eachDeep, filterDeep, keysDeep etc? Tree traversal extension for lodash. | ||
@@ -72,3 +72,3 @@ [![npm](https://img.shields.io/npm/v/deepdash.svg)](https://www.npmjs.com/package/deepdash) [![Travis (.org)](https://api.travis-ci.org/YuriGor/deepdash.svg?branch=master)](https://travis-ci.org/YuriGor/deepdash) [![Coverage Status](https://coveralls.io/repos/github/YuriGor/deepdash/badge.svg?branch=master)](https://coveralls.io/github/YuriGor/deepdash?branch=master) <br> | ||
if(key=="skip"){ | ||
return false;//return false explicitly to skip iteration over current value's children | ||
return false; // return false explicitly to skip iteration over current value's children | ||
} | ||
@@ -114,13 +114,17 @@ }); | ||
### eachDeep (forEachDeep) | ||
`_.eachDeep(object, [iteratee=_.identity], [options={ track: false }])` <br> | ||
Invokes given callback for each field and element of given object or array, nested too. | ||
**Arguments:** | ||
- object: (Object) The object to iterate over. | ||
- \[iteratee\]: (Function) The function invoked per iteration. | ||
`iteratee` will be called with: | ||
- value, key, path, depth, parent, parentKey, parentPath, \[parents\] | ||
- \[options\]: (Object) | ||
- \[track\]: (Boolean) track parents from current back to the root, useful for circular reference detecting. If true, `iteratee` will have additional `parents` object argument with `values`, `keys` and `paths` arrays inside. | ||
```js | ||
_.eachDeep( | ||
obj, // The object to iterate over | ||
iteratee=_.identity, // The function invoked per iteration | ||
options={ | ||
track: false /* track parents from current back to the root, | ||
useful for circular reference detecting. | ||
If true, `iteratee` will have additional `parents` object argument | ||
with `values`, `keys` and `paths` arrays inside. */ | ||
} | ||
) | ||
``` | ||
**Example:** | ||
@@ -147,12 +151,19 @@ ```js | ||
``` | ||
### indexate | ||
`_.indexate(object, [options={ checkCircular: false, includeCircularPath: true, leafsOnly: false }])` <br> | ||
Creates an 'index' flat object with paths as keys and corresponding values. | ||
**Arguments:** | ||
- object: (Object) The object to iterate over. | ||
- \[options\]: (Object) | ||
- \[checkCircular\]: (Boolean) check each value to not be one of the parents, to avoid circular references. | ||
- \[includeCircularPath\]: (Boolean) if found some circular reference - include path to it into result or skip it. Option ignored if `checkCircular:false`. | ||
- \[leafsOnly\]: (Boolean) return paths to childless values only. By default all the paths will be returned, including parents. | ||
```js | ||
_.indexate( | ||
obj, // The object to iterate over. | ||
options={ | ||
checkCircular: false, // Check each value to not be one of the parents, to avoid circular references. | ||
includeCircularPath: true, /* If found some circular reference - include path to it into result or skip it. | ||
Option ignored if `checkCircular:false`. */ | ||
leafsOnly: true /* Return paths to childless values only by default. | ||
Or all the paths will be returned, including parents, if set to false. */ | ||
} | ||
) | ||
``` | ||
@@ -183,11 +194,17 @@ **Example:** | ||
### paths (keysDeep) | ||
`_.paths(object, [iteratee=_.identity], [options={ checkCircular: false, includeCircularPath: true, leafsOnly: false }])` <br> | ||
Creates an array of the paths of object or array. | ||
**Arguments:** | ||
- object: (Object) The object to iterate over. | ||
- \[options\]: (Object) | ||
- \[checkCircular\]: (Boolean) check each value to not be one of the parents, to avoid circular references. | ||
- \[includeCircularPath\]: (Boolean) if found some circular reference - include path to it into result or skip it. Option ignored if `checkCircular:false`. | ||
- \[leafsOnly\]: (Boolean) return paths to childless values only. By default all the paths will be returned, including parents. | ||
```js | ||
_.paths( | ||
obj, // The object to iterate over. | ||
options = { | ||
checkCircular: false, // Check each value to not be one of the parents, to avoid circular references. | ||
includeCircularPath: true, /* If found some circular reference - include path to it into result or skip it. | ||
Option ignored if `checkCircular:false`. */ | ||
leafsOnly: true /* Return paths to childless values only by default. | ||
Or all the paths will be returned, including parents, if set to false. */ | ||
} | ||
) | ||
``` | ||
@@ -212,3 +229,3 @@ **Example:** | ||
}, | ||
},{ leafsOnly: true }); | ||
},{ leafsOnly: false }); | ||
console.log(paths); | ||
@@ -233,3 +250,121 @@ ``` | ||
### filterDeep | ||
Returns and object with childs of your choice only | ||
```js | ||
_.filterDeep( | ||
obj, // The object to iterate over. | ||
predicate, /* The predicate is invoked with eight arguments: | ||
(value, key|index, path, depth, parent, parentKey, parentPath, parents) | ||
- If predicate returns `true` - value will be deeply cloned to result object | ||
no further iteration over children of this value will be performed. | ||
- If predicate returns `false` - value will be completely excluded from the result object | ||
no further iteration over children of this value will be performed. | ||
- If predicate returns `undefined` - current path will only appear in the result object | ||
if some child elements will pass the filter during subsequent iterations. */ | ||
options = { | ||
checkCircular: false, // Check each value to not be one of the parents, to avoid circular references. | ||
keepCircular: true, // result object will contain circular references if they passed the filter. | ||
// replaceCircularBy: <value>, // Specify the value to replace circular references by. | ||
leafsOnly: true, /* Call predicate for childless values only by default. | ||
Or all the intermediate objects will be passed into predicate, including parents, if set to false. */ | ||
condense: true, // Condense result object, since exluding some paths may produce sparse arrays | ||
cloneDeep: _.cloneDeep, // Method to use for deep cloning values, lodash cloneDeep by default. | ||
} | ||
) | ||
``` | ||
**Example:** | ||
```js | ||
let things = { | ||
things: [ | ||
{ name: 'something', good: false }, | ||
{ | ||
name: 'another thing', good: true, | ||
children: [ | ||
{ name: 'child thing 1', good: false }, | ||
{ name: 'child thing 2', good: true }, | ||
{ name: 'child thing 3', good: false }, | ||
], | ||
}, | ||
{ | ||
name: 'something else', good: true, | ||
subItem: { name: 'sub-item', good: false }, | ||
subItem2: { name: 'sub-item-2', good: true }, | ||
}, | ||
], | ||
}; | ||
let filtrate = _.filterDeep( | ||
things, | ||
(value, key, path, depth, parent, parentKey, parentPath, parents) => { | ||
if (key == 'name' && parent.good) return true; | ||
if (key == 'good' && value == true) return true; | ||
}, | ||
{ leafsOnly: true } | ||
); | ||
console.log(filtrate); | ||
``` | ||
Console: | ||
``` | ||
{ things: | ||
[ { name: 'another thing', | ||
good: true, | ||
children: [ { name: 'child thing 2', good: true } ] }, | ||
{ name: 'something else', | ||
good: true, | ||
subItem2: { name: 'sub-item-2', good: true } } ] } | ||
``` | ||
### condense | ||
Makes sparsed aray non-sparsed. This method mutates object. | ||
```js | ||
_.condense( | ||
arr // array to condense | ||
); | ||
``` | ||
**Example:** | ||
```js | ||
let arr = ['a', 'b', 'c', 'd', 'e']; | ||
delete arr[1]; | ||
console.log(arr); | ||
delete arr[3]; | ||
console.log(arr); | ||
_.condense(arr); | ||
console.log(arr); | ||
``` | ||
Console: | ||
``` | ||
[ 'a', <1 empty item>, 'c', 'd', 'e' ] | ||
[ 'a', <1 empty item>, 'c', <1 empty item>, 'e' ] | ||
[ 'a', 'c', 'e' ] | ||
``` | ||
### condenseDeep | ||
Make all the arrays in the object non-sparsed. | ||
```js | ||
_.condenseDeep( | ||
obj, // The object to iterate over. | ||
options = { | ||
checkCircular: false, // Check each value to not be one of the parents, to avoid circular references. | ||
} | ||
); | ||
``` | ||
**Example:** | ||
```js | ||
let obj = { arr: ['a', 'b', { c: [1, , 2, , 3] }, 'd', 'e'] }; | ||
delete obj.arr[1]; | ||
delete obj.arr[3]; | ||
_.condenseDeep(obj); | ||
console.log(obj); | ||
``` | ||
Console: | ||
``` | ||
{ arr: [ 'a', { c: [ 1, 2, 3 ] }, 'e' ] } | ||
``` | ||
### Other traversal methods | ||
Feel free [to request](https://github.com/YuriGor/deepdash/issues/new) other methods implementation. |
@@ -76,6 +76,6 @@ 'use strict'; | ||
it('Array',()=>{ | ||
it('Array', () => { | ||
let c = 0; | ||
_.eachDeep( | ||
[demo,demo], | ||
[demo, demo], | ||
(value, key, path, depth, parent, parentKey, parentPath) => { | ||
@@ -89,3 +89,3 @@ if (key == 'skip') return false; | ||
it('String',()=>{ | ||
it('String', () => { | ||
let c = 0; | ||
@@ -101,2 +101,24 @@ _.eachDeep( | ||
}); | ||
it('empty props', () => { | ||
let c = 0; | ||
var o = { a: 0, b: 1, c: 2 }; | ||
delete o.b; | ||
_.eachDeep(o, () => { | ||
c++; | ||
}); | ||
expect(c).equal(2); | ||
c = 0; | ||
var a = ['a', 'b', 'c']; | ||
delete a[1]; | ||
_.eachDeep(a, () => { | ||
c++; | ||
}); | ||
expect(c).equal(2); | ||
c = 0; | ||
var slots = ['start', , 'middle', , 'finish']; | ||
_.eachDeep(slots, () => { | ||
c++; | ||
}); | ||
expect(c).equal(3); | ||
}); | ||
}); |
'use strict'; | ||
const chai = require('chai'), | ||
should = chai.should(), | ||
// should = chai.should(), | ||
expect = chai.expect, | ||
assert = require('assert'), | ||
// assert = require('assert'), | ||
_ = require('../deepdash')(require('lodash')); | ||
@@ -16,31 +16,28 @@ | ||
it('Count paths', () => { | ||
let index = _.indexate(demo); | ||
let index = _.indexate(demo, { leafsOnly: false }); | ||
expect(_.size(index)).equal(30); | ||
}); | ||
it('Array', () => { | ||
let index = _.indexate([demo, demo]); | ||
let index = _.indexate([demo, demo], { leafsOnly: false }); | ||
expect(_.size(index)).equal(62); | ||
}); | ||
it('Count paths circular', () => { | ||
let index = _.indexate(circular, { checkCircular: true }); | ||
let index = _.indexate(circular, { checkCircular: true, leafsOnly: false }); | ||
// console.log(index); | ||
expect(_.size(index)).equal(23); | ||
expect(_.size(index)).equal(25); | ||
index = _.indexate(circular, { | ||
checkCircular: true, | ||
leafsOnly: false, | ||
includeCircularPath: false, | ||
}); | ||
// console.log(index); | ||
expect(_.size(index)).equal(20); | ||
expect(_.size(index)).equal(22); | ||
}); | ||
it('Chaining', () => { | ||
let index = _(demo) | ||
.indexate() | ||
.indexate({ leafsOnly: false }) | ||
.value(); | ||
expect(_.size(index)).equal(30); | ||
}); | ||
it('alias paths', () => { | ||
let index = _.paths(demo); | ||
expect(_.size(index)).equal(30); | ||
}); | ||
it('returns empty array', () => { | ||
it('returns empty obj', () => { | ||
let index = _.indexate(1); | ||
@@ -75,11 +72,23 @@ expect(index).to.deep.equal({}); | ||
let index = _.indexate(circular, { checkCircular: true, leafsOnly: true }); | ||
expect(_.size(index)).equal(10); | ||
expect(_.size(index)).equal(12); | ||
index = _.indexate(circular, { | ||
checkCircular: true, | ||
includeCircularPath: false, | ||
leafsOnly: true | ||
leafsOnly: true, | ||
}); | ||
expect(_.size(index)).equal(9); | ||
}); | ||
it('empty props', () => { | ||
var o = { a: 0, b: 1, c: 2 }; | ||
delete o.b; | ||
let index = _.indexate(o); | ||
expect(_.size(index)).equal(2); | ||
var a = ['a', 'b', 'c']; | ||
delete a[1]; | ||
index = _.indexate(a); | ||
expect(_.size(index)).equal(2); | ||
var slots = ['start', , 'middle', , 'finish']; | ||
index = _.indexate(slots); | ||
expect(_.size(index)).equal(3); | ||
}); | ||
}); |
@@ -8,15 +8,15 @@ 'use strict'; | ||
// e: circular.a.b, | ||
hi: 'planet', | ||
}, | ||
}, | ||
}, | ||
i: [ | ||
1, | ||
2, | ||
3, | ||
4, | ||
{ hello: 'world' } | ||
], | ||
i: [1, 2, 3, 4, { hello: 'world' }], | ||
}; | ||
circular.a.b.c.e = circular.a.b; | ||
circular.i.push([circular, [circular.a], { j: circular.i[4] }, { k: circular.i[5] }]); | ||
circular.i.push([ | ||
circular, | ||
[circular.a], | ||
{ j: circular.i[4] }, | ||
{ k: circular.i[5] }, | ||
]); | ||
@@ -23,0 +23,0 @@ module.exports = { |
'use strict'; | ||
const chai = require('chai'), | ||
should = chai.should(), | ||
// should = chai.should(), | ||
expect = chai.expect, | ||
assert = require('assert'), | ||
// assert = require('assert'), | ||
_ = require('../deepdash')(require('lodash')); | ||
@@ -16,23 +16,24 @@ | ||
it('Count paths', () => { | ||
let paths = _.paths(demo); | ||
let paths = _.paths(demo, { leafsOnly: false }); | ||
expect(paths.length).equal(30); | ||
}); | ||
it('Array', () => { | ||
let paths = _.paths([demo, demo]); | ||
let paths = _.paths([demo, demo], { leafsOnly: false }); | ||
expect(paths.length).equal(62); | ||
}); | ||
it('Count paths circular', () => { | ||
let paths = _.paths(circular, { checkCircular: true }); | ||
let paths = _.paths(circular, { checkCircular: true, leafsOnly: false }); | ||
// console.log(paths); | ||
expect(paths.length).equal(23); | ||
expect(paths.length).equal(25); | ||
paths = _.paths(circular, { | ||
checkCircular: true, | ||
includeCircularPath: false, | ||
leafsOnly: false, | ||
}); | ||
// console.log(paths); | ||
expect(paths.length).equal(20); | ||
expect(paths.length).equal(22); | ||
}); | ||
it('Chaining', () => { | ||
let paths = _(demo) | ||
.paths() | ||
.paths({ leafsOnly: false }) | ||
.value(); | ||
@@ -42,3 +43,3 @@ expect(paths.length).equal(30); | ||
it('alias keysDeep', () => { | ||
let paths = _.keysDeep(demo); | ||
let paths = _.keysDeep(demo, { leafsOnly: false }); | ||
expect(paths.length).equal(30); | ||
@@ -91,11 +92,23 @@ }); | ||
let paths = _.paths(circular, { checkCircular: true, leafsOnly: true }); | ||
expect(paths.length).equal(10); | ||
expect(paths.length).equal(12); | ||
paths = _.paths(circular, { | ||
checkCircular: true, | ||
includeCircularPath: false, | ||
leafsOnly: true | ||
leafsOnly: true, | ||
}); | ||
expect(paths.length).equal(9); | ||
}); | ||
it('empty props', () => { | ||
var o = { a: 0, b: 1, c: 2 }; | ||
delete o.b; | ||
let paths = _.paths(o); | ||
expect(paths.length).equal(2); | ||
var a = ['a', 'b', 'c']; | ||
delete a[1]; | ||
paths = _.paths(a); | ||
expect(paths.length).equal(2); | ||
var slots = ['start', , 'middle', , 'finish']; | ||
paths = _.paths(slots); | ||
expect(paths.length).equal(3); | ||
}); | ||
}); |
@@ -55,10 +55,13 @@ 'use strict'; | ||
it('default', () => { | ||
let keys = _.keysDeep({ | ||
a: { | ||
b: { | ||
c: [1, 2, 3], | ||
'hello world': {}, | ||
let keys = _.keysDeep( | ||
{ | ||
a: { | ||
b: { | ||
c: [1, 2, 3], | ||
'hello world': {}, | ||
}, | ||
}, | ||
}, | ||
}); | ||
{ leafsOnly: false } | ||
); | ||
expect(keys).to.deep.equal([ | ||
@@ -94,1 +97,72 @@ 'a', | ||
}); | ||
describe('filterDeep', () => { | ||
it('Count paths', () => { | ||
let things = { | ||
things: [ | ||
{ name: 'something', good: false }, | ||
{ | ||
name: 'another thing', | ||
good: true, | ||
children: [ | ||
{ name: 'child thing 1', good: false }, | ||
{ name: 'child thing 2', good: true }, | ||
{ name: 'child thing 3', good: false }, | ||
], | ||
}, | ||
{ | ||
name: 'something else', | ||
good: true, | ||
subItem: { name: 'sub-item', good: false }, | ||
subItem2: { name: 'sub-item-2', good: true }, | ||
}, | ||
], | ||
}; | ||
let filtrate = _.filterDeep( | ||
things, | ||
(value, key, path, depth, parent, parentKey, parentPath, parents) => { | ||
if (key == 'name' && parent.good) return true; | ||
if (key == 'good' && value == true) return true; | ||
}, | ||
{ leafsOnly: true } | ||
); | ||
// console.log(filtrate); | ||
filtrate.should.to.deep.equal({ | ||
things: [ | ||
{ | ||
name: 'another thing', | ||
good: true, | ||
children: [{ name: 'child thing 2', good: true }], | ||
}, | ||
{ | ||
name: 'something else', | ||
good: true, | ||
subItem2: { name: 'sub-item-2', good: true }, | ||
}, | ||
], | ||
}); | ||
}); | ||
}); | ||
describe('condenseDeep', () => { | ||
it('condense', () => { | ||
let arr = ['a', 'b', 'c', 'd', 'e']; | ||
delete arr[1]; | ||
// console.log(arr); | ||
delete arr[3]; | ||
// console.log(arr); | ||
_.condense(arr); | ||
// console.log(arr); | ||
arr.should.to.deep.equal(['a', 'c', 'e']); | ||
}); | ||
it('condenseDeep', () => { | ||
let obj = { arr: ['a', 'b', { c: [1, , 2, , 3] }, 'd', 'e'] }; | ||
delete obj.arr[1]; | ||
// console.log(obj); | ||
delete obj.arr[3]; | ||
// console.log(obj); | ||
_.condenseDeep(obj); | ||
// console.log(obj); | ||
obj.should.to.deep.equal({ arr: ['a', { c: [1, 2, 3] }, 'e'] }); | ||
}); | ||
}); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
54060
21
1379
365
10
4