A tree traversal library.
npm install --save tree-visit
OR
yarn add tree-visit
The recommended way to use tree-visit
is by calling defineTree(getChildren)
, where getChildren
is a function which returns a node's children as an array. The defineTree
API returns an object containing every library function with the getChildren
option already set.
You may alternately import individual functions, e.g. visit
, and pass the { getChildren }
option when calling them. Importing individual functions can reduce your bundle size to the bear minimum (though the entire library is small and has 0 dependencies, so this may not be necessary).
Most callback functions, such as getChildren
, predicate
, onEnter
, and onLeave
, are passed an IndexPath
as the second argument, containing an array of integer indexes that identify that node. The root node is implicitly included in the IndexPath
(i.e. there's no 0
first in every IndexPath
).
Returns a node by its IndexPath
.
Type: function access<T>(node: T, indexPath: IndexPath, options: BaseOptions<T>): T
import { access } from 'tree-visit'
const getChildren = (node) => node.children || []
const rootNode = {
name: 'a',
children: [
{ name: 'b' },
{
name: 'c',
children: [{ name: 'd' }],
},
],
}
access(rootNode, [1, 0], { getChildren })
// #=> { name: 'd' }
Returns an array of each node in an IndexPath
.
Type: function accessPath<T>(node: T, indexPath: IndexPath, options: BaseOptions<T>): T
import { accessPath } from 'tree-visit'
const getChildren = (node) => node.children || []
const rootNode = {
name: 'a',
children: [
{ name: 'b' },
{
name: 'c',
children: [{ name: 'd' }],
},
],
}
access(rootNode, [1, 0], { getChildren })
// #=> [{ name: 'a', children: [...] }, { name: 'c', children: [...] }, { name: 'd' }]
Returns a version of every library function with the getChildren
option already set.
This also allows for more concise calls to most functions.
Type: function defineTree<T>(baseOptions: BaseOptions<T>): Tree<T>
import { defineTree } from 'tree-visit'
const getChildren = (node) => node.children || []
const { visit, find } = defineTree({ getChildren })
const rootNode = {
name: 'a',
children: [
{ name: 'b' },
{
name: 'c',
children: [{ name: 'd' }],
},
],
}
visit(rootNode, (node) => {
console.log(node)
})
// #=> a, b, c, d
find(rootNode, (node) => node.name === 'd')
// #=> { name: 'd' }
Generate a diagram of the tree, as a string.
Type: function diagram<T>(node: T, options: DiagramOptions<T>): string
import { diagram } from 'tree-visit'
const getChildren = (node) => node.children || []
const getLabel = (node) => node.name
const rootNode = {
name: 'a',
children: [
{ name: 'b' },
{
name: 'c',
children: [{ name: 'd' }],
},
],
}
diagram(rootNode, { getChildren, getLabel })
// #=> a
// #=> ├── b
// #=> └── c / d
Find a node matching a predicate function.
Type: function find<T>(node: T, options: FindOptions<T>): T | undefined
import { find } from 'tree-visit'
const getChildren = (node) => node.children || []
const rootNode = {
name: 'a',
children: [
{ name: 'b' },
{
name: 'c',
children: [{ name: 'd' }],
},
],
}
find(rootNode, { getChildren, predicate: (node) => node.name === 'd' })
// #=> { name: 'd' }
Find all nodes matching a predicate function.
Type: findAll<T>(node: T, options: FindOptions<T>): T[]
import { findAll } from 'tree-visit'
const getChildren = (node) => node.children || []
const rootNode = {
name: 'a',
children: [
{ name: 'b' },
{
name: 'c',
children: [{ name: 'd' }],
},
],
}
findAll(rootNode, { getChildren, predicate: (node) => node.name === 'd' })
// #=> [{ name: 'd' }]
Find the IndexPath
of a node matching a predicate function.
Type: findIndexPath<T>(node: T, options: FindOptions<T>): T[]
import { findIndexPath } from 'tree-visit'
const getChildren = (node) => node.children || []
const rootNode = {
name: 'a',
children: [
{ name: 'b' },
{
name: 'c',
children: [{ name: 'd' }],
},
],
}
findIndexPath(rootNode, { getChildren, predicate: (node) => node.name === 'd' })
// #=> [1, 0]
Find the IndexPath
of all nodes matching a predicate function.
Type: findAllIndexPaths<T>(node: T, options: FindOptions<T>): T[]
import { findAllIndexPaths } from 'tree-visit'
const getChildren = (node) => node.children || []
const rootNode = {
name: 'a',
children: [
{ name: 'b' },
{
name: 'c',
children: [{ name: 'd' }],
},
],
}
findAllIndexPaths(rootNode, {
getChildren,
predicate: (node) => node.name === 'c' || node.name === 'd',
})
// #=> [[1], [1, 0]]
Returns an array containing the root node and all of its descendants.
This is analogous to Array.prototype.flat
for flattening arrays.
Type: function flat<T>(node: T, options: BaseOptions<T>): T[]
import { flat } from 'tree-visit'
const getChildren = (node) => node.children || []
const rootNode = {
name: 'a',
children: [
{ name: 'b' },
{
name: 'c',
children: [{ name: 'd' }],
},
],
}
flat(rootNode, { getChildren }).map((node) => node.name)
// #=> ['a', 'b', 'c', 'd']
Visit each node in the tree, calling an optional onEnter
and onLeave
for each.
From onEnter
:
- return nothing or
undefined
to continue - return
"skip"
to skip the children of that node and the subsequentonLeave
- return
"stop"
to end traversal
From onLeave
:
- return nothing or
undefined
to continue - return
"stop"
to end traversal
Type: function visit<T>(node: T, options: VisitOptions<T>): void
import { visit } from 'tree-visit'
const getChildren = (node) => node.children || []
const rootNode = {
name: 'a',
children: [
{ name: 'b' },
{
name: 'c',
children: [{ name: 'd' }],
},
],
}
visit(rootNode, {
getChildren,
onEnter: (node) => {
console.log(node)
},
})
// #=> a, b, c, d