Traverse and transform objects by visiting every node on a recursive walk.
negative.js
var traverse = require('traverse');
var obj = [ 5, 6, -3, [ 7, 8, -2, 1 ], { f : 10, g : -13 } ];
traverse(obj).forEach(function (x) {
if (x < 0) this.update(x + 128);
});
console.dir(obj);
Output:
[ 5, 6, 125, [ 7, 8, 126, 1 ], { f: 10, g: 115 } ]
leaves.js
var traverse = require('traverse');
var obj = {
a : [1,2,3],
b : 4,
c : [5,6],
d : { e : [7,8], f : 9 },
};
var leaves = traverse(obj).reduce(function (acc, x) {
if (this.isLeaf) acc.push(x);
return acc;
}, []);
console.dir(leaves);
Output:
[ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
Each method that takes a callback has a context (its this
object) with these
attributes:
The present node on the recursive walk
An array of string keys from the root to the present node
The context of the node's parent.
This is undefined
for the root node.
The name of the key of the present node in its parent.
This is undefined
for the root node.
Whether the present node is the root node
Whether or not the present node is a leaf node (has no children)
Depth of the node within the traversal
If the node equals one of its parents, the circular
attribute is set to the
context of that parent and the traversal progresses no deeper.
Set a new value for the present node.
Remove the current element from the output. If the node is in an Array it will be spliced off. Otherwise it will be deleted from its parent.
Delete the current element from its parent in the output. Calls delete
even on
Arrays.
Call this function before any of the children are traversed.
Call this function after any of the children are traversed.
Call this function before each of the children are traversed.
Call this function after each of the children are traversed.
Execute fn
for each node in the object and return a new object with the
results of the walk. To update nodes in the result use this.update(value)
.
Execute fn
for each node in the object but unlike .map()
, when
this.update()
is called it updates the object in-place.
For each node in the object, perform a
left-fold
with the return value of fn(acc, node)
.
If acc
isn't specified, acc
is set to the root object for the first step
and the root element is skipped.
Returns a boolean, whether the instance value is equal to the supplied object along a deep traversal using some opinionated choices.
Some notes:
-
RegExps are equal if their .toString()s match, but not functions since functions can close over different variables.
-
Date instances are compared using
.getTime()
just likeassert.deepEqual()
. -
Circular references must refer to the same paths within the data structure for both objects. For instance, in this snippet:
var a = [1];
a.push(a); // a = [ 1, *a ]
var b = [1];
b.push(a); // b = [ 1, [ 1, *a ] ]
a
is not the same as b
since even though the expansion is the same, the
circular references in each refer to different paths into the data structure.
However, in:
var c = [1];
c.push(c); // c = [ 1, *c ];
c
is equal to a
in a deepEqual()
because they have the same terminal node
structure.
-
Arguments objects are not arrays and neither are they the same as regular objects.
-
Instances created with
new
of String, Boolean, and Number types are never equal to the native versions.
Return an Array
of every possible non-cyclic path in the object.
Paths are Array
s of string keys.
Return an Array
of every node in the object.
Create a deep clone of the object.
Using npm: npm install traverse
Or check out the repository and link your development copy: git clone http://github.com/substack/js-traverse.git cd js-traverse npm link .
You can test traverse with "expresso":http://github.com/visionmedia/expresso
(npm install expresso
):
js-traverse $ expresso
100% wahoo, your stuff is not broken!
This library formerly had a hash transformation component. It has been moved to the hashish package.