object-scan
Advanced tools
Comparing version 18.0.3 to 18.1.0
@@ -6,2 +6,3 @@ /* compile needles to hierarchical map object */ | ||
import { Wildcard } from './wildcard.js'; | ||
import { Ref } from './ref.js'; | ||
@@ -21,9 +22,9 @@ const LEAF = Symbol('leaf'); | ||
const merge = (input, symbol, value) => { | ||
if (input[symbol] === undefined) { | ||
defineProperty(input, symbol, []); | ||
const merge = (input, symbol, ...values) => { | ||
const target = input[symbol]; | ||
if (target === undefined) { | ||
defineProperty(input, symbol, values); | ||
} else { | ||
target.push(...values.filter((v) => !target.includes(v))); | ||
} | ||
if (!input[symbol].includes(value)) { | ||
input[symbol].push(value); | ||
} | ||
}; | ||
@@ -61,2 +62,3 @@ | ||
const setValues = (input, entries) => defineProperty(input, VALUES, entries); | ||
const addValues = (input, values) => merge(input, VALUES, ...values); | ||
export const getValues = (input) => input[VALUES]; | ||
@@ -87,3 +89,2 @@ | ||
const stack = [[[tower, null]]]; | ||
const wildcards = []; | ||
let excluded = false; | ||
@@ -96,4 +97,3 @@ | ||
} | ||
stack.pop(); | ||
wildcards.pop(); | ||
stack.length -= 2; | ||
} else if (type === 'ADD') { | ||
@@ -107,7 +107,6 @@ if (wc.excluded === true) { | ||
const toAdd = []; | ||
const wcParent = wildcards[wildcards.length - 1]; | ||
const wcParent = stack[stack.length - 2]; | ||
stack[stack.length - 1] | ||
.forEach(([cur]) => onAdd(cur, wc, wcParent, (e) => toAdd.push([e, cur]))); | ||
stack.push(toAdd); | ||
wildcards.push(wc); | ||
.forEach(([cur, parent]) => onAdd(cur, parent, wc, wcParent, (e) => toAdd.push([e, cur]))); | ||
stack.push(wc, toAdd); | ||
} else { | ||
@@ -123,4 +122,24 @@ stack[stack.length - 1] | ||
iterate(tower, needle, tree, { | ||
onAdd: (cur, wc, wcParent, next) => { | ||
onAdd: (cur, parent, wc, wcParent, next) => { | ||
addNeedle(cur, needle); | ||
if (wc instanceof Ref) { | ||
if (wc.left === true) { | ||
if (wc.isStarRec) { | ||
wc.setPointer(cur); | ||
} | ||
wc.setNode({}); | ||
ctx.stack.push(cur, wc.node, true); | ||
next(wc.node); | ||
} else { | ||
// eslint-disable-next-line no-param-reassign | ||
wc.target = 'target' in wcParent ? wcParent.target : parent[wcParent.value]; | ||
ctx.stack.push(wc.target, wc.node, true); | ||
if (wc.pointer !== null) { | ||
next(wc.pointer); | ||
wc.setPointer(null); | ||
} | ||
next(cur); | ||
} | ||
return; | ||
} | ||
const redundantRecursion = ( | ||
@@ -139,3 +158,3 @@ wcParent !== undefined | ||
cur[wc.value] = child; | ||
ctx.stack.push(cur, child); | ||
ctx.stack.push(cur, child, false); | ||
if (ctx.orderByNeedles) { | ||
@@ -147,2 +166,5 @@ setOrder(child, ctx.counter); | ||
next(cur[wc.value]); | ||
} else { | ||
// eslint-disable-next-line no-param-reassign | ||
wc.target = cur; | ||
} | ||
@@ -179,8 +201,14 @@ if (wc.isStarRec) { | ||
const { stack } = ctx; | ||
const links = []; | ||
while (stack.length !== 0) { | ||
const link = stack.pop(); | ||
const child = stack.pop(); | ||
const parent = stack.pop(); | ||
setValues(child, Object.values(child).reverse()); | ||
if (!(VALUES in child)) { | ||
setValues(child, Object.values(child).reverse()); | ||
} | ||
if (link) { | ||
links.push(parent, child); | ||
} | ||
if (isMatch(child)) { | ||
@@ -195,2 +223,8 @@ setHasMatches(child); | ||
for (let idx = 0, len = links.length; idx < len; idx += 2) { | ||
const parent = links[idx]; | ||
const child = links[idx + 1]; | ||
addValues(parent, getValues(child)); | ||
} | ||
if (ctx.useArraySelector === false) { | ||
@@ -197,0 +231,0 @@ const roots = []; |
import assert from 'assert'; | ||
import { defineProperty } from '../generic/helper.js'; | ||
import { Wildcard } from './wildcard.js'; | ||
import { Ref } from './ref.js'; | ||
@@ -58,3 +59,3 @@ const IS_EXCLUDED = Symbol('is-excluded'); | ||
}, | ||
finishElement: (idx, err, fins, { finReq = false } = {}) => { | ||
finishElement: (idx, err, fins, { finReq = false, group = false } = {}) => { | ||
const isFinished = cursor === idx; | ||
@@ -71,2 +72,5 @@ if (isFinished) { | ||
const ele = input.slice(cursor, idx); | ||
if (group && !['**', '++'].includes(ele)) { | ||
throwError('Bad Group Start', input, { char: idx }); | ||
} | ||
if (inArray && !( | ||
@@ -78,4 +82,8 @@ /^[?*+\d]+$/.test(ele) | ||
} | ||
cResult.push(new Wildcard(inArray ? `[${ele}]` : ele, excludeNext)); | ||
excludeNext = false; | ||
if (group) { | ||
cResult.push(new Ref(ele)); | ||
} else { | ||
cResult.push(new Wildcard(inArray ? `[${ele}]` : ele, excludeNext)); | ||
excludeNext = false; | ||
} | ||
cursor = idx + 1; | ||
@@ -108,2 +116,7 @@ } | ||
finishChild(); | ||
assert(Array.isArray(cResult)); | ||
const refMaybe = cResult[cResult.length - 2]; | ||
if (refMaybe instanceof Ref && refMaybe.left === true) { | ||
cResult.push(refMaybe.link); | ||
} | ||
}, | ||
@@ -110,0 +123,0 @@ finalizeResult: () => { |
@@ -39,3 +39,3 @@ import { Wildcard } from './wildcard.js'; | ||
case '{': | ||
result.finishElement(idx, 'Bad Group Start', [null, '!', '.', '[', '{', ','], { finReq: true }); | ||
result.finishElement(idx, 'Bad Group Start', [null, '!', '.', '[', '{', ','], { group: true }); | ||
result.startGroup(); | ||
@@ -42,0 +42,0 @@ break; |
{ | ||
"name": "object-scan", | ||
"type": "module", | ||
"version": "18.0.3", | ||
"version": "18.1.0", | ||
"description": "Traverse object hierarchies using matching and callbacks.", | ||
@@ -6,0 +6,0 @@ "main": "lib/index.js", |
@@ -210,3 +210,3 @@ # Object-Scan | ||
Recursions can be combined with a regex by appending the regex. | ||
Recursions can be combined with a regex or a group by appending the regex or group. | ||
@@ -268,2 +268,67 @@ _Examples_: | ||
### Nested Path Recursion | ||
To match a nested path recursively, | ||
combine arbitrary depth matching with an or-clause. | ||
There are two types of nested path matching: | ||
- `**{...}`: Matches path(s) in group zero or more times | ||
- `++{...}`: Matches path(s) in group one or more times | ||
_Examples_: | ||
<details><summary> <code>['++{[0][1]}']</code> <em>(`cyclic path`)</em> </summary> | ||
<!-- eslint-disable no-undef --> | ||
```js | ||
const haystack = [[[[0, 1], [1, 2]], [[3, 4], [5, 6]]], [[[7, 8], [9, 10]], [[11, 12], [13, 14]]]]; | ||
objectScan(['++{[0][1]}'], { joined: true })(haystack); | ||
// => [ '[0][1][0][1]', '[0][1]' ] | ||
``` | ||
</details> | ||
<details><summary> <code>['++{[0],[1]}']</code> <em>(`nested or`)</em> </summary> | ||
<!-- eslint-disable no-undef --> | ||
```js | ||
const haystack = [[0, 1, 2], [3, 4, 5], [6, 7, 8]]; | ||
objectScan(['++{[0],[1]}'], { joined: true })(haystack); | ||
// => [ '[1][1]', '[1][0]', '[1]', '[0][1]', '[0][0]', '[0]' ] | ||
``` | ||
</details> | ||
<details><summary> <code>['**{[*]}']</code> <em>(`traverse only array`)</em> </summary> | ||
<!-- eslint-disable no-undef --> | ||
```js | ||
const haystack = [[[{ a: [1] }], [2]]]; | ||
objectScan(['**{[*]}'], { joined: true })(haystack); | ||
// => [ '[0][1][0]', '[0][1]', '[0][0][0]', '[0][0]', '[0]' ] | ||
``` | ||
</details> | ||
<details><summary> <code>['**{*}']</code> <em>(`traverse only object`)</em> </summary> | ||
<!-- eslint-disable no-undef --> | ||
```js | ||
const haystack = { a: [0, { b: 1 }], c: { d: 2 } }; | ||
objectScan(['**{*}'], { joined: true })(haystack); | ||
// => [ 'c.d', 'c', 'a' ] | ||
``` | ||
</details> | ||
<details><summary> <code>['a.**{b.c}']</code> <em>(`zero or more times`)</em> </summary> | ||
<!-- eslint-disable no-undef --> | ||
```js | ||
const haystack = { a: { b: { c: { b: { c: 0 } } } } }; | ||
objectScan(['a.**{b.c}'], { joined: true })(haystack); | ||
// => [ 'a.b.c.b.c', 'a.b.c', 'a' ] | ||
``` | ||
</details> | ||
<details><summary> <code>['a.++{b.c}']</code> <em>(`one or more times`)</em> </summary> | ||
<!-- eslint-disable no-undef --> | ||
```js | ||
const haystack = { a: { b: { c: { b: { c: 0 } } } } }; | ||
objectScan(['a.++{b.c}'], { joined: true })(haystack); | ||
// => [ 'a.b.c.b.c', 'a.b.c' ] | ||
``` | ||
</details> | ||
### Exclusion | ||
@@ -270,0 +335,0 @@ |
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
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
66196
14
902
1159