Skip to content

Commit 6b84fdd

Browse files
Iterate over all inclusive ancestors using an ES6 iterator
1 parent 30a872e commit 6b84fdd

File tree

2 files changed

+68
-0
lines changed

2 files changed

+68
-0
lines changed

lib/SymbolTree.js

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,46 @@ class SymbolTree {
379379
return iterator;
380380
}
381381

382+
/**
383+
* Iterate over all inclusive ancestors of the given object
384+
*
385+
* `O(1)` for a single iteration
386+
*
387+
* @method ancestorsIterator
388+
* @memberOf module:symbol-tree#
389+
* @param {Object} object
390+
* @return {Object} An iterable iterator (ES6)
391+
*/
392+
ancestorsIterator(object) {
393+
const _node = this._node.bind(this);
394+
395+
let nextObject = object;
396+
const iterator = {};
397+
398+
iterator.next = function() {
399+
if (!nextObject) {
400+
return {
401+
done : true,
402+
value : object
403+
};
404+
}
405+
406+
const value = nextObject;
407+
nextObject = _node(nextObject).parent;
408+
409+
return {
410+
done : false,
411+
value : value
412+
};
413+
};
414+
415+
iterator[Symbol.iterator] = function() {
416+
return iterator;
417+
};
418+
419+
return iterator;
420+
}
421+
382422
/**
383423
* Iterate over all descendants of the given object (in tree order).
384424
*

test/SymbolTree.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -777,6 +777,34 @@ test('ancestorsToArray with filter', function(t) {
777777
t.end();
778778
});
779779

780+
test('ancestors iterator', function(t) {
781+
const tree = new SymbolTree();
782+
const a = {};
783+
const aa = {};
784+
const ab = {};
785+
const aba = {};
786+
const abaa = {};
787+
const b = {};
788+
789+
tree.insertLast(aa, a);
790+
tree.insertLast(ab, a);
791+
tree.insertLast(aba, ab);
792+
tree.insertLast(abaa, aba);
793+
tree.insertAfter(b, a);
794+
795+
const results = [];
796+
const iterator = tree.ancestorsIterator(abaa);
797+
798+
for (const object of iterator) {
799+
results.push(object);
800+
}
801+
t.deepEqual([abaa, aba, ab, a], results);
802+
t.deepEqual({done: true, value: abaa}, iterator.next());
803+
t.deepEqual({done: true, value: abaa}, iterator.next()); // should keep returning done: true
804+
805+
t.end();
806+
});
807+
780808
test('treeToArray', function(t) {
781809
const tree = new SymbolTree();
782810
const a = {};

0 commit comments

Comments
 (0)