filter recursive function

This commit is contained in:
Timo Hocker 2020-06-08 14:44:09 +02:00
parent 01d90058ab
commit 84ef0f7bc7
4 changed files with 158 additions and 12 deletions

2
Jenkinsfile vendored
View File

@ -5,7 +5,7 @@ pipeline {
VERSION = VersionNumber([
versionNumberString:
'${BUILDS_ALL_TIME}',
versionPrefix: '1.3.',
versionPrefix: '1.4.',
worstResultForIncrement: 'SUCCESS'
])
}

View File

@ -1,6 +1,6 @@
# @sapphirecode/utilities
version: 1.3.x
version: 1.4.x
small utility functions to make much needed features easier to work with
@ -18,28 +18,43 @@ yarn:
```js
const util = require('@sapphirecode/utilities');
```
// cut off decimal places to a specified point
cut off decimal places to a specified point
```js
util.truncate_decimal(12.345678, 2);
// returns 12.34
```
// will return null instead of throwing on invalid json
will return null instead of throwing on invalid json
```js
util.try_parse_json('{{foo');
```
// copy an object to prevent modification of the original
copy an object to prevent modification of the original
```js
const obj = {foo: 'bar'};
const copy = util.copy_object(obj);
copy.foo = 'baz';
console.log(obj.foo); // bar
```
// run a regular expression and get a callback for every result
const data = "foobarfoo";
run a regular expression and get a callback for every result
```js
const data = 'foobarfoo';
const regex = /foo/g;
util.run_regex(regex, data, res => {
util.run_regex(regex, data, (res) => {
console.log(res[0]); // will output 'foo' 2 times
});
```
// check if a variable is null, undefined or NaN
check if a variable is null, undefined or NaN
```js
console.log(util.is_nil(parseInt('abc'))); // true
console.log(util.is_nil('foo')); // false
console.log(util.is_nil(42)); // false
@ -47,6 +62,54 @@ console.log(util.is_nil(null)); // true
console.log(util.is_nil(undefined)); // true
```
filter an array recursively
```js
const to_filter = [
{name: 'include_foo'},
{
name: 'include_bar',
children: [{name: 'foo'}, {name: 'bar'}],
},
{
name: 'baz',
children: [{name: 'include_foo'}, {name: 'bar'}],
},
{
name: 'barbaz',
children: [{name: 'foo'}, {name: 'bar'}],
},
];
const filter = {
field: 'name', // the field the filter will apply on
filter: /^include_.*/iu, // regex filter
};
const result = util.recursive_filter(
to_filter,
[filter], // you can specify multiple filters, they will be connected using AND
'children' // specify which field an objects children are stored in ('children' is default)
);
console.log(JSON.stringify(result, null, 2));
/* output:
[
{ name: 'include_foo' },
{
name: 'include_bar',
children: [
{ name: 'foo' },
{ name: 'bar' }
]
},
{
name: 'baz',
children: [ { name: 'include_foo' } ]
}
]*/
```
## License
MIT © Timo Hocker <timo@scode.ovh>

View File

@ -78,10 +78,46 @@ function is_nil (obj) {
|| (typeof obj === 'number' && isNaN (obj));
}
/**
* filter nested objects
*
* @param {Array<object>} data
* @param {Array<{field: string, filter: RegExp}>} filters
* @returns {Array<object>} filtered data
*/
function recursive_filter (data, filters, children_key = 'children') {
const filtered = [];
for (const e of data) {
let match = true;
for (const filter of filters) {
if (!filter.filter.test (e[filter.field])) {
match = false;
break;
}
}
if (match) {
filtered.push (e);
}
else {
if (typeof e[children_key] === 'undefined')
continue;
e[children_key] = recursive_filter (
e[children_key],
filters,
children_key
);
if (e[children_key].length > 0)
filtered.push (e);
}
}
return filtered;
}
module.exports = {
truncate_decimal,
try_parse_json,
copy_object,
run_regex,
is_nil
is_nil,
recursive_filter
};

View File

@ -100,3 +100,50 @@ test ('check isnil with nan', (t) => {
test ('check isnil with int', (t) => {
t.is (util.is_nil (parseInt ('42')), false);
});
test ('recursive filter', (t) => {
const raw = [
{ name: 'include_foo' },
{
name: 'include_bar',
children: [
{ name: 'foo' },
{ name: 'bar' }
]
},
{
name: 'baz',
children: [
{ name: 'include_foo' },
{ name: 'bar' }
]
},
{
name: 'barbaz',
children: [
{ name: 'foo' },
{ name: 'bar' }
]
}
];
const filtered = [
{ name: 'include_foo' },
{
name: 'include_bar',
children: [
{ name: 'foo' },
{ name: 'bar' }
]
},
{
name: 'baz',
children: [ { name: 'include_foo' } ]
}
];
const filter = {
field: 'name',
filter: /^include_.*/ui
};
const result = util.recursive_filter (raw, [ filter ]);
t.deepEqual (filtered, result);
});