diff --git a/dist/main.cjs.js b/dist/main.cjs.js index c0b1a5db..7e912545 100644 --- a/dist/main.cjs.js +++ b/dist/main.cjs.js @@ -3507,15 +3507,34 @@ class IntervalTree { this.tree_walk(this.root, (node) => visitor(node.item.key, node.item.value)); } - /** Value Mapper. Walk through every node and map node value to another value - * @param callback(value,key) - function to be called for each tree item - */ + /** + * Value Mapper. Walk through every node and map node value to another value + * @param callback(value,key) - function to be called for each tree item + */ map(callback) { const tree = new IntervalTree(); this.tree_walk(this.root, (node) => tree.insert(node.item.key, callback(node.item.value, node.item.key))); return tree; } + /** + * @param {Interval} interval - optional if the iterator is intended to start from the beginning or end + * @param outputMapperFn(value,key) - optional function that maps (value, key) to custom output + * @returns {Iterator} + */ + *iterate(interval, outputMapperFn = (value, key) => value === key ? key.output() : value) { + let node; + if (interval) { + node = this.tree_search_nearest_forward(this.root, new Node(interval)); + } else if (this.root) { + node = this.local_minimum(this.root); + } + while (node) { + yield outputMapperFn(node.item.value, node.item.key); + node = this.tree_successor(node); + } + } + recalc_max(node) { let node_current = node; while (node_current.parent != null) { @@ -3748,6 +3767,21 @@ class IntervalTree { } } + tree_search_nearest_forward(node, search_node) { + let best; + let curr = node; + while (curr && curr != this.nil_node) { + if (curr.less_than(search_node)) { + if (curr.intersect(search_node) && (!best || curr.less_than(best))) best = curr; + curr = curr.right; + } else { + if (!best || curr.less_than(best)) best = curr; + curr = curr.left; + } + } + return best || null; + } + // Original search_interval method; container res support push() insertion // Search all intervals intersecting given one tree_search_interval(node, search_node, res) { @@ -3945,7 +3979,7 @@ class IntervalTree { } height += heightLeft; return height; - }; + } } /** diff --git a/dist/main.esm.js b/dist/main.esm.js index c7ed24cc..c77ed352 100644 --- a/dist/main.esm.js +++ b/dist/main.esm.js @@ -3503,15 +3503,34 @@ class IntervalTree { this.tree_walk(this.root, (node) => visitor(node.item.key, node.item.value)); } - /** Value Mapper. Walk through every node and map node value to another value - * @param callback(value,key) - function to be called for each tree item - */ + /** + * Value Mapper. Walk through every node and map node value to another value + * @param callback(value,key) - function to be called for each tree item + */ map(callback) { const tree = new IntervalTree(); this.tree_walk(this.root, (node) => tree.insert(node.item.key, callback(node.item.value, node.item.key))); return tree; } + /** + * @param {Interval} interval - optional if the iterator is intended to start from the beginning or end + * @param outputMapperFn(value,key) - optional function that maps (value, key) to custom output + * @returns {Iterator} + */ + *iterate(interval, outputMapperFn = (value, key) => value === key ? key.output() : value) { + let node; + if (interval) { + node = this.tree_search_nearest_forward(this.root, new Node(interval)); + } else if (this.root) { + node = this.local_minimum(this.root); + } + while (node) { + yield outputMapperFn(node.item.value, node.item.key); + node = this.tree_successor(node); + } + } + recalc_max(node) { let node_current = node; while (node_current.parent != null) { @@ -3744,6 +3763,21 @@ class IntervalTree { } } + tree_search_nearest_forward(node, search_node) { + let best; + let curr = node; + while (curr && curr != this.nil_node) { + if (curr.less_than(search_node)) { + if (curr.intersect(search_node) && (!best || curr.less_than(best))) best = curr; + curr = curr.right; + } else { + if (!best || curr.less_than(best)) best = curr; + curr = curr.left; + } + } + return best || null; + } + // Original search_interval method; container res support push() insertion // Search all intervals intersecting given one tree_search_interval(node, search_node, res) { @@ -3941,7 +3975,7 @@ class IntervalTree { } height += heightLeft; return height; - }; + } } /** diff --git a/dist/main.umd.js b/dist/main.umd.js index b90fd647..d0f818f3 100644 --- a/dist/main.umd.js +++ b/dist/main.umd.js @@ -3509,15 +3509,34 @@ this.tree_walk(this.root, (node) => visitor(node.item.key, node.item.value)); } - /** Value Mapper. Walk through every node and map node value to another value - * @param callback(value,key) - function to be called for each tree item - */ + /** + * Value Mapper. Walk through every node and map node value to another value + * @param callback(value,key) - function to be called for each tree item + */ map(callback) { const tree = new IntervalTree(); this.tree_walk(this.root, (node) => tree.insert(node.item.key, callback(node.item.value, node.item.key))); return tree; } + /** + * @param {Interval} interval - optional if the iterator is intended to start from the beginning or end + * @param outputMapperFn(value,key) - optional function that maps (value, key) to custom output + * @returns {Iterator} + */ + *iterate(interval, outputMapperFn = (value, key) => value === key ? key.output() : value) { + let node; + if (interval) { + node = this.tree_search_nearest_forward(this.root, new Node(interval)); + } else if (this.root) { + node = this.local_minimum(this.root); + } + while (node) { + yield outputMapperFn(node.item.value, node.item.key); + node = this.tree_successor(node); + } + } + recalc_max(node) { let node_current = node; while (node_current.parent != null) { @@ -3750,6 +3769,21 @@ } } + tree_search_nearest_forward(node, search_node) { + let best; + let curr = node; + while (curr && curr != this.nil_node) { + if (curr.less_than(search_node)) { + if (curr.intersect(search_node) && (!best || curr.less_than(best))) best = curr; + curr = curr.right; + } else { + if (!best || curr.less_than(best)) best = curr; + curr = curr.left; + } + } + return best || null; + } + // Original search_interval method; container res support push() insertion // Search all intervals intersecting given one tree_search_interval(node, search_node, res) { @@ -3947,7 +3981,7 @@ } height += heightLeft; return height; - }; + } } /** diff --git a/package.json b/package.json index d9022454..6d352a86 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@flatten-js/core", - "version": "1.4.3", + "version": "1.4.4", "description": "Javascript library for 2d geometry", "main": "dist/main.cjs.js", "umd:main": "dist/main.umd.js",