Skip to content

Commit 6a99b44

Browse files
committed
Merge PR#46 simple iterator implementation
Add update index.d.ts and documentation Build packages, upgrade version to minor 1.1.0
1 parent 83da347 commit 6a99b44

13 files changed

+1722
-1938
lines changed

dist/main.cjs.js

+38-4
Original file line numberDiff line numberDiff line change
@@ -392,15 +392,34 @@ class IntervalTree {
392392
this.tree_walk(this.root, (node) => visitor(node.item.key, node.item.value));
393393
}
394394

395-
/** Value Mapper. Walk through every node and map node value to another value
396-
* @param callback(value,key) - function to be called for each tree item
397-
*/
395+
/**
396+
* Value Mapper. Walk through every node and map node value to another value
397+
* @param callback(value,key) - function to be called for each tree item
398+
*/
398399
map(callback) {
399400
const tree = new IntervalTree();
400401
this.tree_walk(this.root, (node) => tree.insert(node.item.key, callback(node.item.value, node.item.key)));
401402
return tree;
402403
}
403404

405+
/**
406+
* @param {Interval} interval - optional if the iterator is intended to start from the beginning or end
407+
* @param outputMapperFn(value,key) - optional function that maps (value, key) to custom output
408+
* @returns {Iterator}
409+
*/
410+
*iterate(interval, outputMapperFn = (value, key) => value === key ? key.output() : value) {
411+
let node;
412+
if (interval) {
413+
node = this.tree_search_nearest_forward(this.root, new Node(interval));
414+
} else if (this.root) {
415+
node = this.local_minimum(this.root);
416+
}
417+
while (node) {
418+
yield outputMapperFn(node.item.value, node.item.key);
419+
node = this.tree_successor(node);
420+
}
421+
}
422+
404423
recalc_max(node) {
405424
let node_current = node;
406425
while (node_current.parent != null) {
@@ -633,6 +652,21 @@ class IntervalTree {
633652
}
634653
}
635654

655+
tree_search_nearest_forward(node, search_node) {
656+
let best;
657+
let curr = node;
658+
while (curr && curr != this.nil_node) {
659+
if (curr.less_than(search_node)) {
660+
if (curr.intersect(search_node) && (!best || curr.less_than(best))) best = curr;
661+
curr = curr.right;
662+
} else {
663+
if (!best || curr.less_than(best)) best = curr;
664+
curr = curr.left;
665+
}
666+
}
667+
return best || null;
668+
}
669+
636670
// Original search_interval method; container res support push() insertion
637671
// Search all intervals intersecting given one
638672
tree_search_interval(node, search_node, res) {
@@ -830,7 +864,7 @@ class IntervalTree {
830864
}
831865
height += heightLeft;
832866
return height;
833-
};
867+
}
834868
}
835869

836870
exports.Interval = Interval;

dist/main.esm.js

+38-4
Original file line numberDiff line numberDiff line change
@@ -388,15 +388,34 @@ class IntervalTree {
388388
this.tree_walk(this.root, (node) => visitor(node.item.key, node.item.value));
389389
}
390390

391-
/** Value Mapper. Walk through every node and map node value to another value
392-
* @param callback(value,key) - function to be called for each tree item
393-
*/
391+
/**
392+
* Value Mapper. Walk through every node and map node value to another value
393+
* @param callback(value,key) - function to be called for each tree item
394+
*/
394395
map(callback) {
395396
const tree = new IntervalTree();
396397
this.tree_walk(this.root, (node) => tree.insert(node.item.key, callback(node.item.value, node.item.key)));
397398
return tree;
398399
}
399400

401+
/**
402+
* @param {Interval} interval - optional if the iterator is intended to start from the beginning or end
403+
* @param outputMapperFn(value,key) - optional function that maps (value, key) to custom output
404+
* @returns {Iterator}
405+
*/
406+
*iterate(interval, outputMapperFn = (value, key) => value === key ? key.output() : value) {
407+
let node;
408+
if (interval) {
409+
node = this.tree_search_nearest_forward(this.root, new Node(interval));
410+
} else if (this.root) {
411+
node = this.local_minimum(this.root);
412+
}
413+
while (node) {
414+
yield outputMapperFn(node.item.value, node.item.key);
415+
node = this.tree_successor(node);
416+
}
417+
}
418+
400419
recalc_max(node) {
401420
let node_current = node;
402421
while (node_current.parent != null) {
@@ -629,6 +648,21 @@ class IntervalTree {
629648
}
630649
}
631650

651+
tree_search_nearest_forward(node, search_node) {
652+
let best;
653+
let curr = node;
654+
while (curr && curr != this.nil_node) {
655+
if (curr.less_than(search_node)) {
656+
if (curr.intersect(search_node) && (!best || curr.less_than(best))) best = curr;
657+
curr = curr.right;
658+
} else {
659+
if (!best || curr.less_than(best)) best = curr;
660+
curr = curr.left;
661+
}
662+
}
663+
return best || null;
664+
}
665+
632666
// Original search_interval method; container res support push() insertion
633667
// Search all intervals intersecting given one
634668
tree_search_interval(node, search_node, res) {
@@ -826,7 +860,7 @@ class IntervalTree {
826860
}
827861
height += heightLeft;
828862
return height;
829-
};
863+
}
830864
}
831865

832866
export { Interval, Node, IntervalTree as default };

dist/main.umd.js

+38-4
Original file line numberDiff line numberDiff line change
@@ -394,15 +394,34 @@
394394
this.tree_walk(this.root, (node) => visitor(node.item.key, node.item.value));
395395
}
396396

397-
/** Value Mapper. Walk through every node and map node value to another value
398-
* @param callback(value,key) - function to be called for each tree item
399-
*/
397+
/**
398+
* Value Mapper. Walk through every node and map node value to another value
399+
* @param callback(value,key) - function to be called for each tree item
400+
*/
400401
map(callback) {
401402
const tree = new IntervalTree();
402403
this.tree_walk(this.root, (node) => tree.insert(node.item.key, callback(node.item.value, node.item.key)));
403404
return tree;
404405
}
405406

407+
/**
408+
* @param {Interval} interval - optional if the iterator is intended to start from the beginning or end
409+
* @param outputMapperFn(value,key) - optional function that maps (value, key) to custom output
410+
* @returns {Iterator}
411+
*/
412+
*iterate(interval, outputMapperFn = (value, key) => value === key ? key.output() : value) {
413+
let node;
414+
if (interval) {
415+
node = this.tree_search_nearest_forward(this.root, new Node(interval));
416+
} else if (this.root) {
417+
node = this.local_minimum(this.root);
418+
}
419+
while (node) {
420+
yield outputMapperFn(node.item.value, node.item.key);
421+
node = this.tree_successor(node);
422+
}
423+
}
424+
406425
recalc_max(node) {
407426
let node_current = node;
408427
while (node_current.parent != null) {
@@ -635,6 +654,21 @@
635654
}
636655
}
637656

657+
tree_search_nearest_forward(node, search_node) {
658+
let best;
659+
let curr = node;
660+
while (curr && curr != this.nil_node) {
661+
if (curr.less_than(search_node)) {
662+
if (curr.intersect(search_node) && (!best || curr.less_than(best))) best = curr;
663+
curr = curr.right;
664+
} else {
665+
if (!best || curr.less_than(best)) best = curr;
666+
curr = curr.left;
667+
}
668+
}
669+
return best || null;
670+
}
671+
638672
// Original search_interval method; container res support push() insertion
639673
// Search all intervals intersecting given one
640674
tree_search_interval(node, search_node, res) {
@@ -832,7 +866,7 @@
832866
}
833867
height += heightLeft;
834868
return height;
835-
};
869+
}
836870
}
837871

838872
exports.Interval = Interval;

docs/Interval.html

+15-4
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
<label for="nav-trigger" class="overlay"></label>
2525

2626
<nav>
27-
<li class="nav-link nav-home-link"><a href="index.html">Home</a></li><li class="nav-heading">Classes</li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="Interval.html">Interval</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Interval.html#.comparable_less_than">comparable_less_than</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Interval.html#.comparable_max">comparable_max</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Interval.html#clone">clone</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Interval.html#equal_to">equal_to</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Interval.html#intersect">intersect</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Interval.html#less_than">less_than</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Interval.html#merge">merge</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Interval.html#not_intersect">not_intersect</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Interval.html#output">output</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="IntervalTree.html">IntervalTree</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="IntervalTree.html#clear">clear</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="IntervalTree.html#exist">exist</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="IntervalTree.html#forEach">forEach</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="IntervalTree.html#insert">insert</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="IntervalTree.html#intersect_any">intersect_any</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="IntervalTree.html#isEmpty">isEmpty</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="IntervalTree.html#map">map</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="IntervalTree.html#remove">remove</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="IntervalTree.html#search">search</a></span></li>
27+
<li class="nav-link nav-home-link"><a href="index.html">Home</a></li><li class="nav-heading">Classes</li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="Interval.html">Interval</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Interval.html#.comparable_less_than">comparable_less_than</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Interval.html#.comparable_max">comparable_max</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Interval.html#clone">clone</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Interval.html#equal_to">equal_to</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Interval.html#intersect">intersect</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Interval.html#less_than">less_than</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Interval.html#merge">merge</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Interval.html#not_intersect">not_intersect</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Interval.html#output">output</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="IntervalTree.html">IntervalTree</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="IntervalTree.html#clear">clear</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="IntervalTree.html#exist">exist</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="IntervalTree.html#forEach">forEach</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="IntervalTree.html#insert">insert</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="IntervalTree.html#intersect_any">intersect_any</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="IntervalTree.html#isEmpty">isEmpty</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="IntervalTree.html#iterate">iterate</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="IntervalTree.html#map">map</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="IntervalTree.html#remove">remove</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="IntervalTree.html#search">search</a></span></li>
2828
</nav>
2929

3030
<div id="main">
@@ -45,7 +45,17 @@ <h2>
4545
Interval
4646
</h2>
4747

48-
<div class="class-description">Interval is a pair of numbers or a pair of any comparable objects on which may be defined predicates*equal*, *less* and method *max(p1, p1)* that returns maximum in a pair.When interval is an object rather than pair of numbers, this object should have properties *low*, *high*, *max*and implement methods *less_than(), equal_to(), intersect(), not_intersect(), clone(), output()*.Two static methods *comparable_max(), comparable_less_than()* define how to compare values in pair. <br/>This interface is described in typescript definition file *index.d.ts*Axis aligned rectangle is an example of such interval.We may look at rectangle as an interval between its low left and top right corners.See **Box** class in [flatten-js](https://github.com/alexbol99/flatten-js) library as the exampleof Interval interface implementation</div>
48+
<div class="class-description">Interval is a pair of numbers or a pair of any comparable objects on which may be defined predicates
49+
*equal*, *less* and method *max(p1, p1)* that returns maximum in a pair.
50+
When interval is an object rather than pair of numbers, this object should have properties *low*, *high*, *max*
51+
and implement methods *less_than(), equal_to(), intersect(), not_intersect(), clone(), output()*.
52+
Two static methods *comparable_max(), comparable_less_than()* define how to compare values in pair. <br/>
53+
This interface is described in typescript definition file *index.d.ts*
54+
55+
Axis aligned rectangle is an example of such interval.
56+
We may look at rectangle as an interval between its low left and top right corners.
57+
See **Box** class in [flatten-js](https://github.com/alexbol99/flatten-js) library as the example
58+
of Interval interface implementation</div>
4959

5060

5161
</header>
@@ -67,7 +77,8 @@ <h4 class="name" id="Interval"><span class="type-signature"></span>new Interval<
6777

6878

6979
<div class="description">
70-
Accept two comparable values and creates new instance of intervalPredicate Interval.comparable_less(low, high) supposed to return true on these values
80+
Accept two comparable values and creates new instance of interval
81+
Predicate Interval.comparable_less(low, high) supposed to return true on these values
7182
</div>
7283

7384

@@ -1600,7 +1611,7 @@ <h4 class="name" id="output"><span class="type-signature"></span>output<span cla
16001611
<br class="clear">
16011612

16021613
<footer>
1603-
Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.6.3</a> on Sat Jul 30 2022 12:04:03 GMT+0300 (Israel Daylight Time) using the Minami theme.
1614+
Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.6.3</a> on Sun Sep 10 2023 14:11:35 GMT+0300 (Israel Daylight Time) using the Minami theme.
16041615
</footer>
16051616

16061617
<script>prettyPrint();</script>

0 commit comments

Comments
 (0)