Skip to content

.explore()

Robert Biro edited this page Oct 13, 2016 · 6 revisions

Traverses all nested objects and arrays in the items array, calling a function for each key/value pair.

.explore(callback[, state])
Parameter Type Default Description
callback Function Function to call for every key/value pair. Parameters: function(key, value, state).
state Object {} Initial value of the state object passed down the hierarchy.

Returns

Returns a reference to the mangler object itself for chaining.

Callback state

Property Type Description
$path String Describes the current value's path from the root of the iteration.
$parent Instance Points to the object which has the current value at the given key.
$parentPath String The path of the parent from the root of the iteration.
$prop String The last known property name of the value. If the current value is an array element, it looks further up the path. If the it's an object property, state.$prop is the same as key. Could be an empty string if there's no object property in the path.

Callback function

The callback function is called for each key/value pair in all iterable objects in the .items[ ] array, traversing items recursively. For arrays, the array index is passed as the key and the item is passed as the value parameter. For objects, the callback function is called for each property with the property name in key and the property value in value.

If value is an iterable object, returning false from the callback function will prevent .explore() to go further and traverse value itself.

Apart from object literals and arrays, other typed objects may be made iterable and could be traversed. See Mangler.registerType() for details.

The $path property of the state parameter is the full reference of the current object relative to the mangler object's .items array.

If we create a mangler object from the following object:

{ children: [{ name: 'Child' }] }

then the callback parameters for the name property would be:

callback('name', 'Child', {
	$path: '[0].children[0].name',
	$parent: { name: 'Child' },
	$parentPath: '[0].children[0]',
	$prop: 'name'
})

The initial value of the state callback parameter can be set by passing an object to the .explore() method. It will be passed down the hierarchy, but changes will only be visible from the same level down. When .explore() goes into a child object or array, it creates a shallow copy of the state object's properties to pass on. You can use any properties apart from the built-in $-prefixed ones, which will be overwritten.

Example 1

data = {
	object1: {},
	object2: {},
	array1: [{}, {}, {}],
	array2: [{}, {}, {}]
};

// Use .explore() to add object properties using a counter in the state object

Mangler(data).explore(function(key, value, state) {

	if(Mangler.isObject(value)) {
		state.counter += 1;
		value.counter = state.counter;
	}

}, { counter: 0 });

/*
	data = {
		counter: 1,
		object1: { counter: 2 },
		object2: { counter: 3 },
		array1: [{ counter: 4 }, { counter: 5 }, { counter: 6 }],
		array2: [{ counter: 4 }, { counter: 5 }, { counter: 6 }]
	}
*/

As the method traverses array1 and array2, the state object is reset to its previous value, before it started processing the arrays.

The above example is only to explain the state object. Please note that there is no guarantee that object properties will be traversed in any particular order.

Example 2

The .explore() method is useful for processing tree structures. The state object can be used to collect data from the parents and pass it down to the child nodes. In the following example, we add a depth property to all objects by increasing a counter in the state object when we start processing an array:

data = {
	name: 'Root',
	children: [
		{
			name: 'Child 1',
			children: [
				{
					name: 'Sub-child 1'
				},
				{
					name: 'Sub-child 2'
				}
			]
		},
		{
			name: 'Child 2'
		}
	]
};

Mangler(data).explore(function(k, v, state) {
	if(Mangler.isArray(v)) {
		state.depth += 1;
	} else if(Mangler.isObject(v)) {
		v.depth = state.depth;
	}
}, { depth: 0 });

/*
	data = {
		depth: 0,
		name: 'Root',
		children: [
			{
				depth: 1,
				name: 'Child 1',
				children: [
					{
						depth: 2,
						name: 'Sub-child 1'
					},
					{
						depth: 2,
						name: 'Sub-child 2'
					}
				]
			},
			{
				depth: 1,
				name: 'Child 2'
			}
		]
	}
*/

Learning Mangler.js

Optional Modules

Reference

Clone this wiki locally