[d24f17c] | 1 | # traverse <sup>[![Version Badge][npm-version-svg]][package-url]</sup>
|
---|
| 2 |
|
---|
| 3 | [![github actions][actions-image]][actions-url]
|
---|
| 4 | [![coverage][codecov-image]][codecov-url]
|
---|
| 5 | [![License][license-image]][license-url]
|
---|
| 6 | [![Downloads][downloads-image]][downloads-url]
|
---|
| 7 |
|
---|
| 8 | [![npm badge][npm-badge-png]][package-url]
|
---|
| 9 |
|
---|
| 10 | Traverse and transform objects by visiting every node on a recursive walk.
|
---|
| 11 |
|
---|
| 12 | # examples
|
---|
| 13 |
|
---|
| 14 | ## transform negative numbers in-place
|
---|
| 15 |
|
---|
| 16 | negative.js
|
---|
| 17 |
|
---|
| 18 | ````javascript
|
---|
| 19 | var traverse = require('traverse');
|
---|
| 20 | var obj = [ 5, 6, -3, [ 7, 8, -2, 1 ], { f : 10, g : -13 } ];
|
---|
| 21 |
|
---|
| 22 | traverse(obj).forEach(function (x) {
|
---|
| 23 | if (x < 0) this.update(x + 128);
|
---|
| 24 | });
|
---|
| 25 |
|
---|
| 26 | console.dir(obj);
|
---|
| 27 | ````
|
---|
| 28 |
|
---|
| 29 | Output:
|
---|
| 30 |
|
---|
| 31 | [ 5, 6, 125, [ 7, 8, 126, 1 ], { f: 10, g: 115 } ]
|
---|
| 32 |
|
---|
| 33 | ## collect leaf nodes
|
---|
| 34 |
|
---|
| 35 | leaves.js
|
---|
| 36 |
|
---|
| 37 | ````javascript
|
---|
| 38 | var traverse = require('traverse');
|
---|
| 39 |
|
---|
| 40 | var obj = {
|
---|
| 41 | a : [1,2,3],
|
---|
| 42 | b : 4,
|
---|
| 43 | c : [5,6],
|
---|
| 44 | d : { e : [7,8], f : 9 },
|
---|
| 45 | };
|
---|
| 46 |
|
---|
| 47 | var leaves = traverse(obj).reduce(function (acc, x) {
|
---|
| 48 | if (this.isLeaf) acc.push(x);
|
---|
| 49 | return acc;
|
---|
| 50 | }, []);
|
---|
| 51 |
|
---|
| 52 | console.dir(leaves);
|
---|
| 53 | ````
|
---|
| 54 |
|
---|
| 55 | Output:
|
---|
| 56 |
|
---|
| 57 | [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
|
---|
| 58 |
|
---|
| 59 | ## scrub circular references
|
---|
| 60 |
|
---|
| 61 | scrub.js:
|
---|
| 62 |
|
---|
| 63 | ````javascript
|
---|
| 64 | var traverse = require('traverse');
|
---|
| 65 |
|
---|
| 66 | var obj = { a : 1, b : 2, c : [ 3, 4 ] };
|
---|
| 67 | obj.c.push(obj);
|
---|
| 68 |
|
---|
| 69 | var scrubbed = traverse(obj).map(function (x) {
|
---|
| 70 | if (this.circular) this.remove()
|
---|
| 71 | });
|
---|
| 72 | console.dir(scrubbed);
|
---|
| 73 | ````
|
---|
| 74 |
|
---|
| 75 | output:
|
---|
| 76 |
|
---|
| 77 | { a: 1, b: 2, c: [ 3, 4 ] }
|
---|
| 78 |
|
---|
| 79 | # methods
|
---|
| 80 |
|
---|
| 81 | Each method that takes an `fn` uses the context documented below in the context
|
---|
| 82 | section.
|
---|
| 83 |
|
---|
| 84 | ## .map(fn)
|
---|
| 85 |
|
---|
| 86 | Execute `fn` for each node in the object and return a new object with the
|
---|
| 87 | results of the walk. To update nodes in the result use `this.update(value)`.
|
---|
| 88 |
|
---|
| 89 | ## .forEach(fn)
|
---|
| 90 |
|
---|
| 91 | Execute `fn` for each node in the object but unlike `.map()`, when
|
---|
| 92 | `this.update()` is called it updates the object in-place.
|
---|
| 93 |
|
---|
| 94 | ## .reduce(fn, acc)
|
---|
| 95 |
|
---|
| 96 | For each node in the object, perform a
|
---|
| 97 | [left-fold](http://en.wikipedia.org/wiki/Fold_(higher-order_function))
|
---|
| 98 | with the return value of `fn(acc, node)`.
|
---|
| 99 |
|
---|
| 100 | If `acc` isn't specified, `acc` is set to the root object for the first step
|
---|
| 101 | and the root element is skipped.
|
---|
| 102 |
|
---|
| 103 | ## .paths()
|
---|
| 104 |
|
---|
| 105 | Return an `Array` of every possible non-cyclic path in the object.
|
---|
| 106 | Paths are `Array`s of string keys.
|
---|
| 107 |
|
---|
| 108 | ## .nodes()
|
---|
| 109 |
|
---|
| 110 | Return an `Array` of every node in the object.
|
---|
| 111 |
|
---|
| 112 | ## .clone()
|
---|
| 113 |
|
---|
| 114 | Create a deep clone of the object.
|
---|
| 115 |
|
---|
| 116 | ## .get(path)
|
---|
| 117 |
|
---|
| 118 | Get the element at the array `path`.
|
---|
| 119 |
|
---|
| 120 | ## .set(path, value)
|
---|
| 121 |
|
---|
| 122 | Set the element at the array `path` to `value`.
|
---|
| 123 |
|
---|
| 124 | ## .has(path)
|
---|
| 125 |
|
---|
| 126 | Return whether the element at the array `path` exists.
|
---|
| 127 |
|
---|
| 128 | # context
|
---|
| 129 |
|
---|
| 130 | Each method that takes a callback has a context (its `this` object) with these
|
---|
| 131 | attributes:
|
---|
| 132 |
|
---|
| 133 | ## this.node
|
---|
| 134 |
|
---|
| 135 | The present node on the recursive walk
|
---|
| 136 |
|
---|
| 137 | ## this.path
|
---|
| 138 |
|
---|
| 139 | An array of string keys from the root to the present node
|
---|
| 140 |
|
---|
| 141 | ## this.parent
|
---|
| 142 |
|
---|
| 143 | The context of the node's parent.
|
---|
| 144 | This is `undefined` for the root node.
|
---|
| 145 |
|
---|
| 146 | ## this.key
|
---|
| 147 |
|
---|
| 148 | The name of the key of the present node in its parent.
|
---|
| 149 | This is `undefined` for the root node.
|
---|
| 150 |
|
---|
| 151 | ## this.isRoot, this.notRoot
|
---|
| 152 |
|
---|
| 153 | Whether the present node is the root node
|
---|
| 154 |
|
---|
| 155 | ## this.isLeaf, this.notLeaf
|
---|
| 156 |
|
---|
| 157 | Whether or not the present node is a leaf node (has no children)
|
---|
| 158 |
|
---|
| 159 | ## this.level
|
---|
| 160 |
|
---|
| 161 | Depth of the node within the traversal
|
---|
| 162 |
|
---|
| 163 | ## this.circular
|
---|
| 164 |
|
---|
| 165 | If the node equals one of its parents, the `circular` attribute is set to the
|
---|
| 166 | context of that parent and the traversal progresses no deeper.
|
---|
| 167 |
|
---|
| 168 | ## this.update(value, stopHere=false)
|
---|
| 169 |
|
---|
| 170 | Set a new value for the present node.
|
---|
| 171 |
|
---|
| 172 | All the elements in `value` will be recursively traversed unless `stopHere` is
|
---|
| 173 | true.
|
---|
| 174 |
|
---|
| 175 | ## this.remove(stopHere=false)
|
---|
| 176 |
|
---|
| 177 | Remove the current element from the output. If the node is in an Array it will
|
---|
| 178 | be spliced off. Otherwise it will be deleted from its parent.
|
---|
| 179 |
|
---|
| 180 | ## this.delete(stopHere=false)
|
---|
| 181 |
|
---|
| 182 | Delete the current element from its parent in the output. Calls `delete` even on
|
---|
| 183 | Arrays.
|
---|
| 184 |
|
---|
| 185 | ## this.before(fn)
|
---|
| 186 |
|
---|
| 187 | Call this function before any of the children are traversed.
|
---|
| 188 |
|
---|
| 189 | You can assign into `this.keys` here to traverse in a custom order.
|
---|
| 190 |
|
---|
| 191 | ## this.after(fn)
|
---|
| 192 |
|
---|
| 193 | Call this function after any of the children are traversed.
|
---|
| 194 |
|
---|
| 195 | ## this.pre(fn)
|
---|
| 196 |
|
---|
| 197 | Call this function before each of the children are traversed.
|
---|
| 198 |
|
---|
| 199 | ## this.post(fn)
|
---|
| 200 |
|
---|
| 201 | Call this function after each of the children are traversed.
|
---|
| 202 |
|
---|
| 203 |
|
---|
| 204 | # install
|
---|
| 205 |
|
---|
| 206 | Using [npm](http://npmjs.org) do:
|
---|
| 207 |
|
---|
| 208 | $ npm install traverse
|
---|
| 209 |
|
---|
| 210 | # license
|
---|
| 211 |
|
---|
| 212 | MIT
|
---|
| 213 |
|
---|
| 214 | [package-url]: https://npmjs.org/package/traverse
|
---|
| 215 | [npm-version-svg]: https://versionbadg.es/ljharb/traverse.svg
|
---|
| 216 | [deps-svg]: https://david-dm.org/ljharb/traverse.svg
|
---|
| 217 | [deps-url]: https://david-dm.org/ljharb/traverse
|
---|
| 218 | [dev-deps-svg]: https://david-dm.org/ljharb/traverse/dev-status.svg
|
---|
| 219 | [dev-deps-url]: https://david-dm.org/ljharb/traverse#info=devDependencies
|
---|
| 220 | [npm-badge-png]: https://nodei.co/npm/traverse.png?downloads=true&stars=true
|
---|
| 221 | [license-image]: https://img.shields.io/npm/l/traverse.svg
|
---|
| 222 | [license-url]: LICENSE
|
---|
| 223 | [downloads-image]: https://img.shields.io/npm/dm/traverse.svg
|
---|
| 224 | [downloads-url]: https://npm-stat.com/charts.html?package=traverse
|
---|
| 225 | [codecov-image]: https://codecov.io/gh/ljharb/traverse/branch/main/graphs/badge.svg
|
---|
| 226 | [codecov-url]: https://app.codecov.io/gh/ljharb/traverse/
|
---|
| 227 | [actions-image]: https://img.shields.io/endpoint?url=https://github-actions-badge-u3jn4tfpocch.runkit.sh/ljharb/traverse
|
---|
| 228 | [actions-url]: https://github.com/ljharb/traverse/actions
|
---|