Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New nodesAtDepth(depth) function #178

Open
benjaminpreiss opened this issue May 7, 2021 · 3 comments
Open

New nodesAtDepth(depth) function #178

benjaminpreiss opened this issue May 7, 2021 · 3 comments

Comments

@benjaminpreiss
Copy link

benjaminpreiss commented May 7, 2021

Hey Mike

Great work. For tree traversal it would be great to have a function that returns all nodes at a certain depth.
Example (taken from source code for leaves()):

export default function(depth) {
  var nodes = [];
  this.eachBefore(function(node) {
    if (node.depth === depth) {
      nodes.push(node);
    }
  });
  return nodes;
}

kind regards Benjamin

@Fil
Copy link
Member

Fil commented May 7, 2021

We should probably cut short when we're at the desired depth, and avoid a traversal of the branches that are deeper.

@benjaminpreiss
Copy link
Author

benjaminpreiss commented May 8, 2021

@Fil Yeah, true... Thinking about this, it would be useful to extend iterator.js as well as create another function called eachToDepth:

First, the changes to iterator.js:

export default function*(depth = this.height) {
  var node = this, current, next = [node], children, i, n;
  do {
    current = next.reverse(), next = [];
    while (node = current.pop()) {
      yield node;
      if ((children = node.children) && node.depth < depth) {
        for (i = 0, n = children.length; i < n; ++i) {
          next.push(children[i]);
        }
      }
    }
  } while (next.length);
}

Now the new eachToDepth.js file (leveraging our changed iterator):

export default function(callback, depth, that) {
  let index = -1;
  for (const node of this[Symbol.iterator](depth)) {
    callback.call(that, node, ++index, this);
  }
  return this;
}

Then we can use the changes above to construct nodesAtDepth.js:

export default function(depth) {
  const nodes = []
  this.eachToDepth(function(node) {
    if (node.depth === depth) {
      nodes.push(node);
    }
  }, depth);
  return nodes
}

The above proposals include nodes at the specified depth (traverse tree breadth first including descendants with specified depth)

@benjaminpreiss
Copy link
Author

Or maybe we don't even need eachToDepth.js...

In that case nodesAtDepth.js would be:

export default function(depth) {
  const nodes = []
  for (const node of this[Symbol.iterator](depth)) {
    if (node.depth === depth) {
      nodes.push(node);
    }
  }
  return nodes
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

2 participants