Skip to content

Commit c32644e

Browse files
author
Jacob Roschen
authored
perf: optimize walk method by 10%-34% (#179)
1 parent e81e9f3 commit c32644e

File tree

1 file changed

+24
-33
lines changed

1 file changed

+24
-33
lines changed

src/jsonpath.js

Lines changed: 24 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -352,33 +352,28 @@ JSONPath.prototype._trace = function (
352352
hasArrExpr));
353353
// eslint-disable-next-line unicorn/prefer-switch -- Part of larger `if`
354354
} else if (loc === '*') { // all child properties
355-
this._walk(
356-
loc, x, val, path, parent, parentPropName, callback,
357-
(m, l, _x, v, p, par, pr, cb) => {
358-
addRet(this._trace(unshift(m, _x), v, p, par, pr, cb,
359-
true, true));
360-
}
361-
);
355+
this._walk(val, (m) => {
356+
addRet(this._trace(
357+
x, val[m], push(path, m), val, m, callback, true, true
358+
));
359+
});
362360
} else if (loc === '..') { // all descendent parent properties
363361
// Check remaining expression with val's immediate children
364362
addRet(
365363
this._trace(x, val, path, parent, parentPropName, callback,
366364
hasArrExpr)
367365
);
368-
this._walk(
369-
loc, x, val, path, parent, parentPropName, callback,
370-
(m, l, _x, v, p, par, pr, cb) => {
371-
// We don't join m and x here because we only want parents,
372-
// not scalar values
373-
if (typeof v[m] === 'object') {
374-
// Keep going with recursive descent on val's
375-
// object children
376-
addRet(this._trace(
377-
unshift(l, _x), v[m], push(p, m), v, m, cb, true
378-
));
379-
}
366+
this._walk(val, (m) => {
367+
// We don't join m and x here because we only want parents,
368+
// not scalar values
369+
if (typeof val[m] === 'object') {
370+
// Keep going with recursive descent on val's
371+
// object children
372+
addRet(this._trace(
373+
expr.slice(), val[m], push(path, m), val, m, callback, true
374+
));
380375
}
381-
);
376+
});
382377
// The parent sel computation is handled in the frame above using the
383378
// ancestor object of val
384379
} else if (loc === '^') {
@@ -408,15 +403,13 @@ JSONPath.prototype._trace = function (
408403
if (this.currPreventEval) {
409404
throw new Error('Eval [?(expr)] prevented in JSONPath expression.');
410405
}
411-
this._walk(
412-
loc, x, val, path, parent, parentPropName, callback,
413-
(m, l, _x, v, p, par, pr, cb) => {
414-
if (this._eval(l.replace(/^\?\((.*?)\)$/u, '$1'), v[m], m, p, par, pr)) {
415-
addRet(this._trace(unshift(m, _x), v, p, par, pr, cb,
416-
true));
417-
}
406+
const safeLoc = loc.replace(/^\?\((.*?)\)$/u, '$1');
407+
this._walk(val, (m) => {
408+
if (this._eval(safeLoc, val[m], m, path, parent, parentPropName)) {
409+
addRet(this._trace(x, val[m], push(path, m), val, m, callback,
410+
true));
418411
}
419-
);
412+
});
420413
} else if (loc[0] === '(') { // [(expr)] (dynamic property/index)
421414
if (this.currPreventEval) {
422415
throw new Error('Eval [(expr)] prevented in JSONPath expression.');
@@ -543,17 +536,15 @@ JSONPath.prototype._trace = function (
543536
return ret;
544537
};
545538

546-
JSONPath.prototype._walk = function (
547-
loc, expr, val, path, parent, parentPropName, callback, f
548-
) {
539+
JSONPath.prototype._walk = function (val, f) {
549540
if (Array.isArray(val)) {
550541
const n = val.length;
551542
for (let i = 0; i < n; i++) {
552-
f(i, loc, expr, val, path, parent, parentPropName, callback);
543+
f(i);
553544
}
554545
} else if (val && typeof val === 'object') {
555546
Object.keys(val).forEach((m) => {
556-
f(m, loc, expr, val, path, parent, parentPropName, callback);
547+
f(m);
557548
});
558549
}
559550
};

0 commit comments

Comments
 (0)