Skip to content

Commit 30a872e

Browse files
Convert all inclusive ancestors to an array
1 parent 715c88c commit 30a872e

File tree

2 files changed

+89
-0
lines changed

2 files changed

+89
-0
lines changed

lib/SymbolTree.js

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,42 @@ class SymbolTree {
267267
return array;
268268
}
269269

270+
/**
271+
* Append all inclusive ancestors of the given object to an array.
272+
*
273+
* `O(n)`
274+
*
275+
* @method ancestorsToArray
276+
* @memberOf module:symbol-tree#
277+
* @param {Object} object
278+
* @param {Object[]} [array=[]]
279+
* @param {Function} [filter] Function to test each object before it is added to the array.
280+
* Invoked with arguments (object). Should return `true` if an object
281+
* is to be included.
282+
* @param {*} [thisArg] Value to use as `this` when executing `filter`.
283+
* @return {Object[]}
284+
*/
285+
ancestorsToArray(object, array, filter, thisArg) {
286+
if (!array) {
287+
array = [];
288+
}
289+
290+
if (!filter) {
291+
filter = returnTrue;
292+
}
293+
294+
let ancestor = object;
295+
296+
while (ancestor) {
297+
if (filter.call(thisArg, ancestor)) {
298+
array.push(ancestor);
299+
}
300+
ancestor = this._node(ancestor).parent;
301+
}
302+
303+
return array;
304+
}
305+
270306
/**
271307
* Append all descendants of the given object to an array (in tree order).
272308
*

test/SymbolTree.js

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -724,6 +724,59 @@ test('children iterator return value using a generator', function(t) {
724724
t.end();
725725
});
726726

727+
test('ancestorsToArray', function(t) {
728+
const tree = new SymbolTree();
729+
const a = {};
730+
const aa = {};
731+
const ab = {};
732+
const aba = {};
733+
const abaa = {};
734+
const b = {};
735+
736+
tree.insertLast(aa, a);
737+
tree.insertLast(ab, a);
738+
tree.insertLast(aba, ab);
739+
tree.insertLast(abaa, aba);
740+
tree.insertAfter(b, a);
741+
742+
t.deepEqual([abaa, aba, ab, a], tree.ancestorsToArray(abaa));
743+
t.deepEqual([aba, ab, a], tree.ancestorsToArray(aba));
744+
t.deepEqual([b], tree.ancestorsToArray(b));
745+
746+
const arr = ['a', 5];
747+
tree.ancestorsToArray(abaa, arr);
748+
t.deepEqual(['a', 5, abaa, aba, ab, a], arr);
749+
750+
t.end();
751+
});
752+
753+
test('ancestorsToArray with filter', function(t) {
754+
const tree = new SymbolTree();
755+
const a = {};
756+
const aa = {};
757+
const ab = {};
758+
const aba = {};
759+
const abaa = {};
760+
const b = {};
761+
762+
tree.insertLast(aa, a);
763+
tree.insertLast(ab, a);
764+
tree.insertLast(aba, ab);
765+
tree.insertLast(abaa, aba);
766+
tree.insertAfter(b, a);
767+
768+
const thisArg = {foo: 'bar'};
769+
const filter = function(object) {
770+
t.equal(this, thisArg);
771+
772+
return object !== abaa && object !== ab;
773+
};
774+
775+
t.deepEqual([aba, a], tree.ancestorsToArray(abaa, null, filter, thisArg));
776+
777+
t.end();
778+
});
779+
727780
test('treeToArray', function(t) {
728781
const tree = new SymbolTree();
729782
const a = {};

0 commit comments

Comments
 (0)