https://github.com/imcuttle/walk-tree
Enhanced and multifunctional tree walker
https://github.com/imcuttle/walk-tree
bfs dfs tree walk
Last synced: 4 months ago
JSON representation
Enhanced and multifunctional tree walker
- Host: GitHub
- URL: https://github.com/imcuttle/walk-tree
- Owner: imcuttle
- License: mit
- Created: 2018-09-17T17:11:26.000Z (over 7 years ago)
- Default Branch: master
- Last Pushed: 2022-01-07T14:49:15.000Z (over 4 years ago)
- Last Synced: 2025-10-13T02:28:07.904Z (8 months ago)
- Topics: bfs, dfs, tree, walk
- Language: JavaScript
- Homepage:
- Size: 97.7 KB
- Stars: 1
- Watchers: 1
- Forks: 0
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: License
Awesome Lists containing this project
README
# @moyuyc/walk-tree
[](https://travis-ci.org/imcuttle/walk-tree)
[](https://codecov.io/github/imcuttle/walk-tree?branch=master)
[](https://www.npmjs.com/package/@moyuyc/walk-tree)
[](https://www.npmjs.com/package/@moyuyc/walk-tree)
[](https://prettier.io/)
[](https://conventionalcommits.org)
Enhanced and multifunctional tree walker
## Installation
```bash
npm install @moyuyc/walk-tree
# or use yarn
yarn add @moyuyc/walk-tree
```
## Usage
```javascript
const walkTree = require('@moyuyc/walk-tree')
walkTree(
{
name: 'root',
children: [{ name: 'c1' }, { name: 'c2' }, { name: 'c3', children: { name: 'c31' } }]
},
node => {
console.log(node.name)
}
)
// prints
// root / c1 / c2 / c3 / c31
// by order
```
## API
### walk
[index.js:54-138](https://github.com/imcuttle/walk-tree/blob/5f0f62e0b76892dcdd2013d2f63ad063de9003a3/index.js#L54-L138 'Source code on GitHub')
#### Parameters
- `tree` {T} - Type `T` should extends Object
- `walker` {(node, ctx: Context) => {}} - Iterator for each node by order
- `opts` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** {object}
- `opts.path` {string} - The child's path on recursive struction (optional, default `'children'`)
- `opts.order` {'pre' | 'post' | 'bfs'}
`pre` means walking the node before walking it's children node by dfs
`post` means walking the node after walking it's children node by dfs
`bfs` means walking the node by bfs
(optional, default `'pre'`)
- `opts.skipVisited` {boolean}
Should skip the node which has been visited. (optional, default `true`)
- `opts.uniquePath` {Function | string | null}
The unique's path for determining the node has been visited (same node) (optional, default `node=>node`)
- `opts.state` {any}
Inject in `context.state` on customized way
Returns **any** walkedTree {T}
## Context
A traversal context.
Four operations are available. Note that depending on the traversal order, some operations have no effects.
#### `remove`
```javascript
walk(rootNode, (node, ctx) => {
if (node.name === 'remove-me') {
return ctx.remove()
}
})
```
#### `replace`
```javascript
walk(rootNode, (node, ctx) => {
if (node.name === 'replace-me') {
return ctx.replace({ name: 'new-me' })
}
})
```
#### `break`
Stop traversal now.
```javascript
walk(rootNode, (node, ctx) => {
if (node.name === 'stop') {
return ctx.break()
}
})
```
#### `skip`
Skip current node, children won't be visited.
```javascript
walk(rootNode, (node, ctx) => {
if (node.name === 'skip') {
return ctx.skip()
}
})
```
#### `parent`
Get the parent of the current node.
#### `depth`
Get the depth of the current node. The depth is the number of ancestors the current node has.
#### `level`
Get the level of current node. The level is the number of ancestors+1 the current node has.
#### `index`
Get the index of the current node.
## FAQ
### How can I get the path of the current node [tree-crawl#37](https://github.com/ngryman/tree-crawl/issues/37)?
#### tl;dr It's easy for DFS, less easy for BFS
If you are using DFS you can use the following utility function:
```javascript
const getPath = context =>
(context.cursor.stack.xs || []).reduce((path, item) => {
if (item.node) {
path.push(item.node)
}
return path
}, [])
```
If you are really concerned about performance, you could read items from the stack directly. Each item has a node and index property that you can use. The first item in the stack can be discarded and will have a node set to null. Be aware that you should not mutate the stack, or it will break the traversal.
If you are using BFS, things gets more complex. A simple hacky way to do so is to traverse the tree using DFS first. You can ad a path property to your nodes using the method above. And then do your regular BFS traversal using that path property.
## Credit
The core algorithm of traverse credits to [tree-crawl](https://github.com/ngryman/tree-crawl)
walk-tree has the different with `tree-crawl`
Because tree-crawl has no idea about the intrinsic structure of your tree, you have to remove the node yourself. `Context#remove` only notifies the traversal code that the structure of the tree has changed.
Otherwise walk-tree would infers your tree by option `path` so don't requires additional remove action.
## Authors
This library is written and maintained by imcuttle, .
## License
MIT