Comparing version
177
index.js
@@ -5,6 +5,110 @@ /** | ||
/** | ||
* Performs deep search on collection to find all matches to the key name, and returns a list of identities containing the matched instances. If no matches found, it returns `undefined`. | ||
* @param {Any} collection | ||
* @param {Any} keyName | ||
* @param {Optional Number} maxDepth | ||
* @return {Array || undefined} Identities | ||
*/ | ||
function deepFilter_Key(collection,keyName,maxDepth=null){ | ||
if(getType(keyName)!=='string') return undefined; | ||
var paths = locateAll_Key(collection,keyName,maxDepth); | ||
if(paths === false) return undefined; | ||
const results = paths.map(path => { | ||
if(path === false) return undefined; | ||
if(path === '') path = keyName; else path += ('.' + keyName); | ||
path = path.split('.'); | ||
var result = collection; | ||
if(!Array.isArray(path)) return result[path]; | ||
path.forEach( key => { result = result[key]; }); | ||
return result; | ||
}) | ||
return results; | ||
} | ||
/** | ||
* Performs deep search for identity on collection to return the location's depth of the first match. If no match found, returns false. | ||
* Performs deep search on collection to find all matches to the key name, returns the location of each match in a string array. If no matches found, it returns `false`. | ||
* @param {Any} collection | ||
* @param {Any} keyName | ||
* @param {Optional Number} maxDepth | ||
* @return {Array || false} Paths | ||
*/ | ||
function locateAll_Key(collection,keyName,maxDepth=null){ | ||
if(getType(keyName)!=='string') return undefined; | ||
var R = []; | ||
function _locateAll_Key(collection,keyName,xKey='',path='',maxDepth=null,currentDepth=0){ | ||
if(xKey===keyName) R[R.length] = path; | ||
var result = false; | ||
if(maxDepth!==null)if(currentDepth>=maxDepth) return result; | ||
if(isIterable(collection)) | ||
for(var i = 0, keys = Object.keys(collection), l = keys.length; i < l; i++ ){ | ||
const key = keys[i], subcollection = collection[key]; | ||
_locateAll_Key(subcollection,keyName,key,(path === '' ? path : path + '.') + key,maxDepth,currentDepth + 1); | ||
} | ||
} | ||
_locateAll_Key(collection,keyName,'','',maxDepth); | ||
R = R.map( path => { | ||
if(getType(path)==='boolean') return path; | ||
if(path==='') return path; | ||
path = path.split('.'); | ||
path.pop(); | ||
path = path.join('.'); | ||
return path; | ||
}); | ||
return R.length === 0 ? false : R; | ||
} | ||
/** | ||
* Performs deep search on collection to find a match to the key name, and returns the first identity containing the match. If no match found, it returns `undefined`. | ||
* @param {Any} collection | ||
* @param {Any} keyName | ||
* @param {Optional number} maxDepth | ||
* @return {Identity || undefined} identity | ||
*/ | ||
function deepGet_Key(collection,keyName,maxDepth=null){ | ||
if(getType(keyName)!=='string') return undefined; | ||
var path = locate_Key(collection,keyName,maxDepth); | ||
if(path === false) return undefined; | ||
if(path === '') path = keyName; else path += ('.' + keyName); | ||
path = path.split('.'); | ||
var result = collection; | ||
if(!Array.isArray(path)) return result[path]; | ||
path.forEach( key => { result = result[key]; }); | ||
return result; | ||
} | ||
/** | ||
* Performs deep search on collection to find a match to the key name, will return the path of the first instance matched. If no match found, it returns `false`. | ||
* @param {Any} collection | ||
* @param {Any} keyName | ||
* @param {Optional number} maxDepth | ||
* @return {String || false} Path | ||
*/ | ||
function locate_Key(collection,keyName,maxDepth=null){ | ||
if(getType(keyName)!=='string') return undefined; | ||
function _locate_Key(collection,keyName,path='',maxDepth,currentDepth=0){ | ||
if(path===keyName) return path; | ||
var result = false; | ||
if(maxDepth!==null)if(currentDepth>=maxDepth) return result; | ||
if(isIterable(collection)) | ||
for(var i = 0, keys = Object.keys(collection), l = keys.length; i < l; i++ ){ | ||
const | ||
key = keys[i], subcollection = collection[key], | ||
res = _locate_Key(subcollection,keyName,key,maxDepth,currentDepth + 1); | ||
if(res) { path = path === '' ? path : path + '.'; result = path + res; break; } | ||
} | ||
return result; | ||
} | ||
var path = _locate_Key(collection,keyName,'',maxDepth,0); | ||
if(getType(path)==='boolean') return path; | ||
if(path==='') return path; | ||
path = path.split('.'); | ||
path.pop(); | ||
path = path.join('.'); | ||
return path; | ||
} | ||
/** | ||
* Performs deep search for identity on collection to return the location's depth of the first match. If no match found, it returns `false`. | ||
* @param {Any} collection | ||
* @param {Any} identity | ||
@@ -323,7 +427,7 @@ * @param {Optional Number} maxDepth | ||
/** | ||
* Performs deep search on collection to find all matches to the identity, will return the entity containing the matched instances. | ||
* Performs deep search on collection to find all matches to the identity, will return a list of identities containing the match. If no matches found, it returns `undefined`. | ||
* @param {Any} collection | ||
* @param {Any} identity | ||
* @param {Optional Number} maxDepth | ||
* @return {Array || undefined} For positive matches returns a string array to the paths of the locations, otherwise undefined | ||
* @return {Array || undefined} identities | ||
*/ | ||
@@ -346,7 +450,7 @@ function deepFilter(collection, identity, maxDepth=null){ | ||
/** | ||
* Performs deep search on collection to find all matches to the identity, returns a string array. | ||
* Performs deep search on collection to find all matches to the identity, returns a string array containing the location of all matches. If no matches found, it returns `false`. | ||
* @param {Any} collection | ||
* @param {Any} identity | ||
* @param {Optional Number} maxDepth | ||
* @return {Array || false} For positive matching returns an array of paths to the locations, otherwise false | ||
* @return {Array || false} Paths | ||
*/ | ||
@@ -376,7 +480,7 @@ function locateAll(collection, identity, maxDepth=null){ | ||
/** | ||
* Performs deep search on collection to find a match to the identity, will return the entity containing of the first instance matched. | ||
* Performs deep search on collection to find a match to the identity, will return the identity containing of the first instance matched. If no matches found, it returns `undefined`. | ||
* @param {Any} collection | ||
* @param {Any} identity | ||
* @param {Optional Number} maxDepth | ||
* @return {String || undefined} For positive match returns the path of the location as string, otherwise undefined | ||
* @return {identity || undefined} identity | ||
*/ | ||
@@ -396,10 +500,9 @@ function deepGet(collection, identity, maxDepth=null){ | ||
/** | ||
* Performs deep search on collection to find a match to the identity, will return the path of the first instance matched. | ||
* Performs deep search on collection to find a match to the identity, will return the path of the first instance matched as string. If no matches found, returns `false`. | ||
* @param {Any} collection | ||
* @param {Any} identity | ||
* @param {Optional number} maxDepth Defines how deep will the function go, before return with a result | ||
* @return {String || False} For positive match returns the path to location as string, otherwise false | ||
* @param {Optional number} maxDepth | ||
* @return {string || false} path | ||
*/ | ||
function locate(collection, identity, maxDepth=null){ | ||
var R; | ||
function _locate(collection, identity, path = '', maxDepth,currentDepth){ | ||
@@ -542,28 +645,32 @@ if(isIterable(identity)) | ||
mitsuketa = { | ||
getType : function(identity) { return getType(identity); }, | ||
sameType : function(identityA,identityB) { return sameType(identityA,identityB); }, | ||
sameStructure : function(identityA,identityB) { return sameStructure(identityA,identityB); }, | ||
identical : function(identityA,identityB) { return identical(identityA,identityB); }, | ||
isIterable : function(identity) { return isIterable(identity); }, | ||
containsKeys : function(identity,keyList) { return containsKeys(identity,keyList); }, | ||
trim : function(identity,keyList) { return trim(identity,keyList); }, | ||
locate : function(collection,identity,maxDepth) { return locate(collection,identity,maxDepth); }, | ||
deepGet : function(collection,identity,maxDepth) { return deepGet(collection,identity,maxDepth); }, | ||
locateAll : function(collection,identity,maxDepth) { return locateAll(collection,identity,maxDepth); }, | ||
deepFilter : function(collection,identity,maxDepth) { return deepFilter(collection,identity,maxDepth); }, | ||
exists : function(collection,identity,maxDepth) { return exists(collection,identity,maxDepth); }, | ||
onlyExisting : function(collection,identities,maxDepth) { return onlyExisting(collection,identities,maxDepth); }, | ||
onlyMissing : function(collection,identities,maxDepth) { return onlyMissing(collection,identities,maxDepth); }, | ||
length : function(identity) { return length(identity); }, | ||
isFalsy : function(identity) { return isFalsy(identity); }, | ||
isTruthy : function(identity) { return isTruthy(identity); }, | ||
foundTruthy : function(collection,identity,maxDepth) { return foundTruthy(collection,identity,maxDepth); }, | ||
onlyTruthy : function(collection,identities,property,maxDepth) { return onlyTruthy(collection,identities,property,maxDepth); }, | ||
foundFalsy : function(collection,identity,maxDepth) { return foundFalsy(collection,identity,maxDepth); }, | ||
onlyFalsy : function(collection,identities,property,maxDepth) { return onlyFalsy(collection,identities,property,maxDepth); }, | ||
countMatches : function(collection,identity,nthDepth,maxDepth) { return countMatches(collection,identity,nthDepth,maxDepth); }, | ||
matchDepth : function(collection,identity,maxDepth) { return matchDepth(collection,identity,maxDepth); }, | ||
maxDepth : function(identity,maxLayer) { return maxDepth(identity,maxLayer); } | ||
getType : function(identity) { return getType(identity); }, | ||
sameType : function(identityA,identityB) { return sameType(identityA,identityB); }, | ||
sameStructure : function(identityA,identityB) { return sameStructure(identityA,identityB); }, | ||
identical : function(identityA,identityB) { return identical(identityA,identityB); }, | ||
isIterable : function(identity) { return isIterable(identity); }, | ||
containsKeys : function(identity,keyList) { return containsKeys(identity,keyList); }, | ||
trim : function(identity,keyList) { return trim(identity,keyList); }, | ||
locate : function(collection,identity,maxDepth) { return locate(collection,identity,maxDepth); }, | ||
deepGet : function(collection,identity,maxDepth) { return deepGet(collection,identity,maxDepth); }, | ||
locateAll : function(collection,identity,maxDepth) { return locateAll(collection,identity,maxDepth); }, | ||
deepFilter : function(collection,identity,maxDepth) { return deepFilter(collection,identity,maxDepth); }, | ||
exists : function(collection,identity,maxDepth) { return exists(collection,identity,maxDepth); }, | ||
onlyExisting : function(collection,identities,maxDepth) { return onlyExisting(collection,identities,maxDepth); }, | ||
onlyMissing : function(collection,identities,maxDepth) { return onlyMissing(collection,identities,maxDepth); }, | ||
length : function(identity) { return length(identity); }, | ||
isFalsy : function(identity) { return isFalsy(identity); }, | ||
isTruthy : function(identity) { return isTruthy(identity); }, | ||
foundTruthy : function(collection,identity,maxDepth) { return foundTruthy(collection,identity,maxDepth); }, | ||
onlyTruthy : function(collection,identities,property,maxDepth) { return onlyTruthy(collection,identities,property,maxDepth); }, | ||
foundFalsy : function(collection,identity,maxDepth) { return foundFalsy(collection,identity,maxDepth); }, | ||
onlyFalsy : function(collection,identities,property,maxDepth) { return onlyFalsy(collection,identities,property,maxDepth); }, | ||
countMatches : function(collection,identity,nthDepth,maxDepth) { return countMatches(collection,identity,nthDepth,maxDepth); }, | ||
matchDepth : function(collection,identity,maxDepth) { return matchDepth(collection,identity,maxDepth); }, | ||
maxDepth : function(identity,maxLayer) { return maxDepth(identity,maxLayer); }, | ||
locate_Key : function(collection,keyName,maxDepth) { return locate_Key(collection,keyName,maxDepth); }, | ||
deepGet_Key : function(collection,keyName,maxDepth) { return deepGet_Key(collection,keyName,maxDepth); }, | ||
locateAll_Key : function(collection,keyName,maxDepth) { return locateAll_Key(collection,keyName,maxDepth); }, | ||
deepFilter_Key : function(collection,keyName,maxDepth) { return deepFilter_Key(collection,keyName,maxDepth); } | ||
} | ||
module.exports = exports = mitsuketa; |
{ | ||
"name": "mitsuketa", | ||
"version": "1.3.3", | ||
"version": "1.3.4", | ||
"description": "A Javascript library that enables you to handle deeply nested objects easily.", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -20,10 +20,9 @@ # Mitsuketa  | ||
1. *maxDepth* parameter is now supported for all functions. | ||
2. Now quality tests provide full coverage of this project. We intend it to keep it that way! | ||
3. Two new functions have been added that complements *maxDepth* parameter support. This will allow you do to more with it. See [*maxDepth*](https://github.com/AndrewRedican/mitsuketa/wiki/v1.3.x#maxdepth-identity--optionalmaxlayer-) and [*matchDepth*](https://github.com/AndrewRedican/mitsuketa/wiki/v1.3.x#matchdepth-collection--identity--optionalmaxdepth-). | ||
4. If you haven't checked it out already, you can learn more about how we [set up and execute tests](https://github.com/AndrewRedican/mitsuketa/wiki/How-to-Create-and-Run-Tests). | ||
1. `locate()`, `deepGet()`, `locateAll()`, `deepFilter()` functions now have a counterpart each that supports deep search by `key` or `property name`. Check them out! [**locate_Key**](https://github.com/AndrewRedican/mitsuketa/wiki/v1.3.x#locate_key-collection--keyname--optionalmaxdepth-), [**deepGet_Key**](https://github.com/AndrewRedican/mitsuketa/wiki/v1.3.x#deepget_key-collection--keyname--optionalmaxdepth-), [**locateAll_Key**](https://github.com/AndrewRedican/mitsuketa/wiki/v1.3.x#locateall_key-collection--keyname--optionalmaxdepth-), [**deepFilter_Key**](https://github.com/AndrewRedican/mitsuketa/wiki/v1.3.x#deepfilter_key-collection--keyname--optionalmaxdepth-) | ||
2. Most of the features so far have focused on obtaining data from complex object trees. Now we are taking an exciting new focus on actual **deeply nested object manipulation**. Check out our [**project board**](https://github.com/AndrewRedican/mitsuketa/projects/1) for a sneak peek to the new features. Feel free suggest any feature that you'd like to see by answering the survey down below. | ||
3. If you haven't checked it out already, you can learn more about how we [set up and execute tests](https://github.com/AndrewRedican/mitsuketa/wiki/How-to-Create-and-Run-Tests). | ||
## Overview | ||
| Method | Description | Parameters/Input | Output | | ||
| Method | Brief Description | Parameters/Input | Output | | ||
| ------------- |-----------------------------| ------| :-----:| | ||
@@ -40,3 +39,3 @@ | [getType](https://github.com/AndrewRedican/mitsuketa/wiki/v1.1.0#gettype-identity-) | Gets `typeof` `identity` also makes distinction between `object`, `null`, and `array` | identity | string | | ||
| [locateAll](https://github.com/AndrewRedican/mitsuketa/wiki/v1.1.0#locateall-collection-identity-optionaldepth--) | Uses `locate` and returns all the paths to all matches | collection, identity | array of string | | ||
| [deepFilter](https://github.com/AndrewRedican/mitsuketa/wiki/v1.1.0#deepfilter-collection-identity-optionaldepth-) | Users `locateAll` and returns an array of all an identites matched inside `collection` | collection, identity | array of identities | | ||
| [deepFilter](https://github.com/AndrewRedican/mitsuketa/wiki/v1.1.0#deepfilter-collection-identity-optionaldepth-) | Uses `locateAll` and returns an array of all an identites matched inside `collection` | collection, identity | array of identities | | ||
| [length](https://github.com/AndrewRedican/mitsuketa/wiki/v1.2.0#length-identity-) | Returns the number of keys or properties contained in `identity` | identity | number | | ||
@@ -54,4 +53,9 @@ | [exists](https://github.com/AndrewRedican/mitsuketa/wiki/v1.2.0#exists-collection-identity-optionaldepth--) | Performs deep search on `collection` for an `identical` match to `identity` | collection, identity | boolean | | ||
| [maxDepth](https://github.com/AndrewRedican/mitsuketa/wiki/v1.3.x#maxdepth-identity--optionalmaxlayer-) | Returns the nth value of the deepest layer of the entire object tree | identity | number | | ||
| [matchDepth](https://github.com/AndrewRedican/mitsuketa/wiki/v1.3.x#matchdepth-collection--identity--optionalmaxdepth-) | Performs deep search for `identity` on `collectio`n to return the location's depth of the first match. If no match found, returns false. | collection, identity | number | | ||
| [matchDepth](https://github.com/AndrewRedican/mitsuketa/wiki/v1.3.x#matchdepth-collection--identity--optionalmaxdepth-) | Performs deep search for `identity` on `collection` to return the location's depth of the first match. If no match found, returns false. | collection, identity | number | | ||
| [locate_Key](https://github.com/AndrewRedican/mitsuketa/wiki/v1.3.x#locate_key-collection--keyname--optionalmaxdepth-) | Performs a deep search by iterating through the `collection`'s entire object tree an returns the path to the first `identical` match that is found as a string of dot . separated property names | collection, key | string | | ||
| [deepGet_Key](https://github.com/AndrewRedican/mitsuketa/wiki/v1.3.x#deepget_key-collection--keyname--optionalmaxdepth-) | Uses `locate_Key` and returns the `indentity`'s container if found in `collection` | collection, key | identity | | ||
| [locateAll_Key](https://github.com/AndrewRedican/mitsuketa/wiki/v1.3.x#locateall_key-collection--keyname--optionalmaxdepth-) | Uses `locate_Key` and returns all the paths to all matches | collection, key | array of string | | ||
| [deepFilter_Key](https://github.com/AndrewRedican/mitsuketa/wiki/v1.3.x#deepfilter_key-collection--keyname--optionalmaxdepth-) | Uses `locateAll` and returns an array of all an identites matched inside `collection` | collection, key | array of identities | | ||
## Built With | ||
@@ -76,2 +80,2 @@ | ||
If you have a minute to spare, can you answer these two questions? | ||
https://www.surveymonkey.com/r/XJ37XSP | ||
https://www.surveymonkey.com/r/XJ37XSP |
124
test/test.js
@@ -1022,2 +1022,126 @@ /** | ||
}); | ||
}); | ||
/** | ||
* | ||
* VERSION 2.0 FEATURES | ||
* | ||
*/ | ||
describe('locate_Key(collection,identity)', function() { | ||
var tests = [ | ||
{args: [bicycles,'date_sold'], expected: '0.sales' }, | ||
{args: [bicycles,'date'], expected: '0.sales.sale_opportunities.0' }, | ||
{args: [bicycles,'silver'], expected: false }, | ||
{args: [bicycles,{name: "Jane O'Neil"}], expected: undefined } | ||
]; | ||
tests.forEach(function(test) { | ||
it(opDescription(2,test.args,test.expected), function() { | ||
var res = mitsuketa.locate_Key(test.args[0],test.args[1]); | ||
assert.equal(stringify(res), stringify(test.expected)); | ||
}); | ||
}); | ||
}); | ||
describe('locate_Key(collection,identity,maxDepth)', function() { | ||
var tests = [ | ||
{args: [bicycles,'date',5], expected: '0.sales.sale_opportunities.0' }, | ||
{args: [bicycles,'date',4], expected: false }, | ||
{args: [bicycles,'date',3], expected: false } | ||
]; | ||
tests.forEach(function(test) { | ||
it(opDescription(3,test.args,test.expected), function() { | ||
var res = mitsuketa.locate_Key(test.args[0],test.args[1],test.args[2]); | ||
assert.equal(stringify(res), stringify(test.expected)); | ||
}); | ||
}); | ||
}); | ||
describe('deepGet_Key(collection,keyName)', function() { | ||
var tests = [ | ||
{args: [bicycles,'date'], expected: 'Dec 19, 2017' }, | ||
{args: [bicycles,'silver'], expected: undefined }, | ||
{args: [bicycles,{name: "Jane O'Neil"}], expected: undefined }, | ||
{args: [bicycles,'type'], expected: 'racing' } | ||
]; | ||
tests.forEach(function(test) { | ||
it(opDescription(2,test.args,test.expected), function() { | ||
var res = mitsuketa.deepGet_Key(test.args[0],test.args[1]); | ||
assert.equal(stringify(res), stringify(test.expected)); | ||
}); | ||
}); | ||
}); | ||
describe('deepGet_Key(collection,keyName,maxDepth)', function() { | ||
var tests = [ | ||
{args: [bicycles,'date',5], expected: 'Dec 19, 2017' }, | ||
{args: [bicycles,'date',4], expected: undefined }, | ||
{args: [bicycles,'date',3], expected: undefined } | ||
]; | ||
tests.forEach(function(test) { | ||
it(opDescription(3,test.args,test.expected), function() { | ||
var res = mitsuketa.deepGet_Key(test.args[0],test.args[1],test.args[2]); | ||
assert.equal(stringify(res), stringify(test.expected)); | ||
}); | ||
}); | ||
}); | ||
describe('locateAll_Key(collection,keyName)', function() { | ||
var res1 = ['0.sales.sale_opportunities.0','0.sales.sale_opportunities.1','1.sales.sale_opportunities.0','1.sales.sale_opportunities.1']; | ||
var tests = [ | ||
{args: [bicycles,'date'], expected: res1 }, | ||
{args: [bicycles,'maker'], expected: ['0','1','2','3'] } | ||
]; | ||
tests.forEach(function(test) { | ||
it(opDescription(2,test.args,test.expected), function() { | ||
var res = mitsuketa.locateAll_Key(test.args[0],test.args[1]); | ||
assert.equal(stringify(res), stringify(test.expected)); | ||
}); | ||
}); | ||
}); | ||
describe('locateAll_Key(collection,keyName,maxDepth)', function() { | ||
var res1 = ['0.sales.sale_opportunities.0','0.sales.sale_opportunities.1','1.sales.sale_opportunities.0','1.sales.sale_opportunities.1']; | ||
var tests = [ | ||
{args: [bicycles,'maker',2], expected: ['0','1','2','3'] }, | ||
{args: [bicycles,'maker',1], expected: false }, | ||
{args: [bicycles,'date',5], expected: res1 }, | ||
{args: [bicycles,'date',4], expected: false } | ||
]; | ||
tests.forEach(function(test) { | ||
it(opDescription(3,test.args,test.expected), function() { | ||
var res = mitsuketa.locateAll_Key(test.args[0],test.args[1],test.args[2]); | ||
assert.equal(stringify(res), stringify(test.expected)); | ||
}); | ||
}); | ||
}); | ||
describe('deepFilter_Key(collection,keyName)', function() { | ||
var tests = [ | ||
{args: [bicycles,'date'], expected: ['Dec 19, 2017','Dec 4, 2017','',''] }, | ||
{args: [bicycles,'maker'], expected: ['breez TM','hyperwheel','hyperwheel','hyperwheel'] } | ||
]; | ||
tests.forEach(function(test) { | ||
it(opDescription(2,test.args,test.expected), function() { | ||
var res = mitsuketa.deepFilter_Key(test.args[0],test.args[1]); | ||
assert.equal(stringify(res), stringify(test.expected)); | ||
}); | ||
}); | ||
}); | ||
describe('deepFilter_Key(collection,keyName,maxDepth)', function() { | ||
var res1 = ['0.sales.sale_opportunities.0','0.sales.sale_opportunities.1','1.sales.sale_opportunities.0','1.sales.sale_opportunities.1']; | ||
var tests = [ | ||
{args: [bicycles,'maker',2], expected: ['breez TM','hyperwheel','hyperwheel','hyperwheel'] }, | ||
{args: [bicycles,'maker',1], expected: undefined }, | ||
{args: [bicycles,'date',5], expected: ['Dec 19, 2017','Dec 4, 2017','',''] }, | ||
{args: [bicycles,'date',4], expected: undefined } | ||
]; | ||
tests.forEach(function(test) { | ||
it(opDescription(3,test.args,test.expected), function() { | ||
var res = mitsuketa.deepFilter_Key(test.args[0],test.args[1],test.args[2]); | ||
assert.equal(stringify(res), stringify(test.expected)); | ||
}); | ||
}); | ||
}); |
97886
14.37%1717
14.54%77
4.05%