carry values between filter runs
This commit is contained in:
parent
141c698351
commit
092e84d8bb
2
Jenkinsfile
vendored
2
Jenkinsfile
vendored
@ -5,7 +5,7 @@ pipeline {
|
||||
VERSION = VersionNumber([
|
||||
versionNumberString:
|
||||
'${BUILDS_ALL_TIME}',
|
||||
versionPrefix: '1.6.',
|
||||
versionPrefix: '1.7.',
|
||||
worstResultForIncrement: 'SUCCESS'
|
||||
])
|
||||
}
|
||||
|
36
README.md
36
README.md
@ -118,9 +118,9 @@ const result = util.recursive_filter(
|
||||
[
|
||||
{
|
||||
filter: /foo bar/iu,
|
||||
field: ['name', 'name_2'] // fields will be joined with a space in between
|
||||
field: ['name', 'name_2'], // fields will be joined with a space in between
|
||||
// {name: 'foo', name_2: 'bar'} will become 'foo bar'
|
||||
}
|
||||
},
|
||||
]
|
||||
);
|
||||
```
|
||||
@ -145,6 +145,38 @@ const result = util.recursive_filter(
|
||||
);
|
||||
```
|
||||
|
||||
field values can be carried to filter runs on children to filter over the entire tree instead of just one element
|
||||
|
||||
```js
|
||||
const to_filter = [
|
||||
{
|
||||
name: 'foo',
|
||||
children: [
|
||||
{ name: 'bar' },
|
||||
{ name: 'baz' },
|
||||
{ foo: 'bar' }
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
const res = util.recursive_filter (
|
||||
to_filter,
|
||||
[ { field: 'name', filter: /foo bar/ui } ], // values will be separaed by a space
|
||||
'children',
|
||||
[ 'name' ] // specify which fields should be carried
|
||||
// the filters will receive the carried values instead of the plain fields
|
||||
);
|
||||
|
||||
/* result:
|
||||
|
||||
[
|
||||
{
|
||||
name: 'foo',
|
||||
children: [ { name: 'bar' } ]
|
||||
}
|
||||
]
|
||||
*/
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
|
49
index.js
49
index.js
@ -78,23 +78,29 @@ function is_nil (obj) {
|
||||
|| (typeof obj === 'number' && isNaN (obj));
|
||||
}
|
||||
|
||||
function check_filter (filter, e) {
|
||||
function get_element_field (element, carried_data, field) {
|
||||
if (typeof carried_data[field] !== 'undefined')
|
||||
return carried_data[field];
|
||||
return element[field];
|
||||
}
|
||||
|
||||
function check_filter (filter, e, carried_data) {
|
||||
const search_str = Array.isArray (filter.field)
|
||||
? filter.field.map ((f) => e[f])
|
||||
? filter.field.map ((f) => get_element_field (e, carried_data, f))
|
||||
.filter ((v) => typeof v !== 'undefined')
|
||||
.join (' ')
|
||||
: e[filter.field];
|
||||
: get_element_field (e, carried_data, filter.field);
|
||||
|
||||
return filter.filter.test (search_str);
|
||||
}
|
||||
|
||||
function check_filters (filters, e, or = false) {
|
||||
function check_filters (filters, e, carried_data, or = false) {
|
||||
for (const filter of filters) {
|
||||
let res = false;
|
||||
if (Array.isArray (filter.or))
|
||||
res = check_filters (filter.or, e, true);
|
||||
res = check_filters (filter.or, e, carried_data, true);
|
||||
else
|
||||
res = check_filter (filter, e);
|
||||
res = check_filter (filter, e, carried_data);
|
||||
|
||||
if (or && res)
|
||||
return true;
|
||||
@ -120,17 +126,36 @@ function check_filters (filters, e, or = false) {
|
||||
/**
|
||||
* filter nested objects
|
||||
*
|
||||
* @param {Array<object>} input
|
||||
* @param {(Filter|FilterOrGroup)[]} filters
|
||||
* @param {Array<object>} input object to filter
|
||||
* @param {(Filter|FilterOrGroup)[]} filters filters
|
||||
* @param {string[]} carry carry data to children to match
|
||||
* @param {object} carried_data internal: carried data
|
||||
* @returns {Array<object>} filtered data
|
||||
*/
|
||||
function recursive_filter (input, filters, children_key = 'children') {
|
||||
function recursive_filter (
|
||||
input,
|
||||
filters,
|
||||
children_key = 'children',
|
||||
carry = [],
|
||||
carried_data = {}
|
||||
) {
|
||||
const data = [ ...input ];
|
||||
const filtered = [];
|
||||
|
||||
for (const c of carry) {
|
||||
if (typeof carried_data[c] !== 'string')
|
||||
carried_data[c] = '';
|
||||
}
|
||||
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
const e = { ...data[i] };
|
||||
data[i] = e;
|
||||
if (check_filters (filters, e)) {
|
||||
const sub_carry = { ...carried_data };
|
||||
for (const c of carry) {
|
||||
if (typeof e[c] !== 'undefined')
|
||||
sub_carry[c] += `${sub_carry[c].length > 0 ? ' ' : ''}${e[c]}`;
|
||||
}
|
||||
if (check_filters (filters, e, sub_carry)) {
|
||||
filtered.push (e);
|
||||
}
|
||||
else {
|
||||
@ -139,7 +164,9 @@ function recursive_filter (input, filters, children_key = 'children') {
|
||||
e[children_key] = recursive_filter (
|
||||
e[children_key],
|
||||
filters,
|
||||
children_key
|
||||
children_key,
|
||||
carry,
|
||||
sub_carry
|
||||
);
|
||||
if (e[children_key].length > 0)
|
||||
filtered.push (e);
|
||||
|
@ -225,3 +225,30 @@ test ('recursive filter with or group', (t) => {
|
||||
|
||||
t.deepEqual (res, to_filter.slice (0, 2));
|
||||
});
|
||||
|
||||
test ('recursive filter carry field', (t) => {
|
||||
const to_filter = [
|
||||
{
|
||||
name: 'foo',
|
||||
children: [
|
||||
{ name: 'bar' },
|
||||
{ name: 'baz' },
|
||||
{ foo: 'bar' }
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
const res = util.recursive_filter (
|
||||
to_filter,
|
||||
[ { field: 'name', filter: /foo bar/ui } ],
|
||||
'children',
|
||||
[ 'name' ]
|
||||
);
|
||||
|
||||
t.deepEqual (res, [
|
||||
{
|
||||
name: 'foo',
|
||||
children: [ { name: 'bar' } ]
|
||||
}
|
||||
]);
|
||||
});
|
||||
|
Loading…
x
Reference in New Issue
Block a user