As the title says I'm searching for the most efficient way to create a flat array output from a recursive function.
The following example produces the correct result but it is kind of slow as it has to create a temporary concatenated array of points for each level of recursion.
class QuadTree {
// ...
// some other methods
// ...
get points() {
if (this.divided) {
// concatenate and return points of all subtrees
return this.subtrees[0].points.concat(
this.subtrees[1].points,
this.subtrees[2].points,
this.subtrees[3].points
);
}
// return _points array of this quadtree
return this._points;
}
}
Is there a way to speed this up?
I would think that this kind of problem is quite common when working with nested/treelike datastructures but I have not found a satisfying solution.
The only thing that I can think of is to replace your accessor property with a function (or perhaps add the function alongside it) and pass the target array in so that it can be filled in directly. Something like:
class QuadTree {
// ...
// some other methods
// ...
getDividedPoints(target = []) {
this.subtrees[0].getDividedPoints(target);
this.subtrees[1].getDivdedPoints(target);
this.subtrees[2].getDivdedPoints(target);
this.subtrees[3].getDivdedPoints(target);
return target;
}
get points() {
if (this.divided) {
return this.getDividedPoints([]);
}
// return _points array of this quadtree
return this._points;
}
}
Or if subtrees
is a normal array, getDividedPoints
could be:
getDividedPoints(target = []) {
this.subtrees.forEach(subtree => subtree.getDividedPoints(target));
return target;
}
Otherwise, since I assume you want to copy this.subtrees[0].points
(rather than inserting into it), concat
's going to be pretty good.
If the subtrees may or may not be divided, you'll need the if
in the function. And I just belatedly noticed the name of the class. :-) So I'd probably just make the four calls:
getPoints(target) {
if (this.divided) {
target = target || [];
this.subtrees[0].getPoints(target);
this.subtrees[1].getPoints(target);
this.subtrees[2].getPoints(target);
this.subtrees[3].getPoints(target);
return target;
}
if (target) {
target.push.apply(target, this._points);
return target;
}
return this._points; // <== If you're really okay with giving this
// to the caller (you were in your original code)
}
get points() {
return this.getDividedPoints([]);
}
...or any of several other spins on that basic idea.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.