From 78e0adb1750546923ac6da44614df060b8e080de Mon Sep 17 00:00:00 2001 From: Adam Janicki Date: Tue, 12 Mar 2024 16:29:10 -0400 Subject: [PATCH 1/3] `walkUp` function --- src/index-fn.js | 1 + src/walkUp.js | 22 ++++++++++++++++++++++ test/walkUp.js | 26 ++++++++++++++++++++++++++ 3 files changed, 49 insertions(+) create mode 100644 src/walkUp.js create mode 100644 test/walkUp.js diff --git a/src/index-fn.js b/src/index-fn.js index f2640da..e03f685 100644 --- a/src/index-fn.js +++ b/src/index-fn.js @@ -9,3 +9,4 @@ export {default as closest} from "./closest.js"; export {default as find} from "./find.js"; export {default as map} from "./map.js"; export {default as walk} from "./walk.js"; +export {default as walkUp} from "./walkUp.js"; diff --git a/src/walkUp.js b/src/walkUp.js new file mode 100644 index 0000000..a72be55 --- /dev/null +++ b/src/walkUp.js @@ -0,0 +1,22 @@ +import * as parents from "./parents.js"; + +/** + * Walk up the tree from the given node, calling the callback on each node. + * @param {object} node + * @param {function} callback + * @returns {any} The first non-undefined value returned by the callback, or the highest ancestor node if no undefined value is ever returned. + */ +export default function walkUp (node, callback) { + let previousNode; + while (node) { + const ret = callback(node); + if (ret !== undefined) { + return ret; + } + previousNode = node; + const parent = parents.getParent.call(this, node); + // TODO: what should happen if parent is undefined (meaning no parent pointers have been set?) + node = parent; + } + return previousNode; +} \ No newline at end of file diff --git a/test/walkUp.js b/test/walkUp.js new file mode 100644 index 0000000..20e1d14 --- /dev/null +++ b/test/walkUp.js @@ -0,0 +1,26 @@ +import walkUp from "../src/walkUp.js"; +import trees from "./utils/trees.js"; +import updateParents from "../src/updateParents.js"; +import copy from "./utils/copy.js" + +const tree = copy(trees[0]); +updateParents(tree); + +export default { + name: "walkUp()", + run (node, cb) { + return walkUp(node, cb); + }, + tests: [ + { + name: "No callback", + args: [tree.right, () => {}], + expect: tree + }, + { + name: "Callback returns a value", + args: [tree.right, n => n.name === "1" ? n : undefined], + expect: tree + } + ] +}; From 47ef510df79b38c51fbd58a3810488cb1be74bef Mon Sep 17 00:00:00 2001 From: Adam Janicki Date: Tue, 19 Mar 2024 09:34:48 -0400 Subject: [PATCH 2/3] lint --- src/walkUp.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/walkUp.js b/src/walkUp.js index 3768ac0..5e4dfe0 100644 --- a/src/walkUp.js +++ b/src/walkUp.js @@ -1,4 +1,4 @@ -import { getParent }from "./parents.js"; +import { getParent } from "./parents.js"; /** * Walk up the tree from the given node, calling the callback on each node. From f3fb08790b4af662e8dd6195329c77054eaa1193 Mon Sep 17 00:00:00 2001 From: Adam Janicki Date: Thu, 28 Mar 2024 14:56:14 -0400 Subject: [PATCH 3/3] add assertion of parent pointers --- src/walkUp.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/walkUp.js b/src/walkUp.js index 5e4dfe0..ee50a89 100644 --- a/src/walkUp.js +++ b/src/walkUp.js @@ -1,4 +1,5 @@ import { getParent } from "./parents.js"; +import { assertParentPointers } from "./util.js"; /** * Walk up the tree from the given node, calling the callback on each node. @@ -12,8 +13,7 @@ export default function walkUp (node, callback) { if (ret !== undefined) { return ret; } - const parent = getParent.call(this, node); - // TODO: what should happen if parent is undefined (meaning no parent pointers have been set?) - node = parent; + assertParentPointers.call(this, node, "Cannot walk up the tree from a node with no parent pointer."); + node = getParent.call(this, node); } }