-
Notifications
You must be signed in to change notification settings - Fork 3
Sample Generators
This page lists sample generators, demonstrating the many different ways to use genData.
The list is divided between standard and custom generators. In all cases, read the generator's description, in order to understand what object type(s) and structure(s) may be returned.
Notice:
- All code samples is available license free.
- Use of these examples is at your own risk.
- By default, genData will scan objects recursively.
Standard generators return a dataset; an array of normalized data objects - each having the same structure and prototype. When studying these generators, consider how the prototyping methods to them might increase their usefulness.
- flagArrays - Structures the dataset.
- genFncs - Filters non-function values, and structures the dataset.
- genRelations - Adds members that reference related data objects.
- genNoRecursion - Avoids an infinite loop when iterating over a recursive object.
- genMenu - Returns data objects that reference and represent a UL tree-menu.
by bemson
Structures the dataset.
Data Object:
- Adds
.isArray- Boolean, Indicates when the value of this data object is an array.
var flagArrays = genData.spawn(function (name, value) {
this.isArray = !!~{}.toString.call(value).indexOf('y');
});by bemson
Filters non-function values, and structures the dataset. Spawned from flagArrays (bemson).
Data Object:
- Adds
.scope- Object, The original scope for the function. The scope iswindowby default.
var genFncs = flagArrays.spawn(function (name, value, parent, dataset, flags) {
if (typeof value === 'function') {
this.scope = (parent && !parent.isArray) ? parent.value : window;
if (parent && parent.isArray && value.name) {
this.name = value.name;
}
} else {
flags.omit = 1;
}
});by bemson
Adds members that reference related data objects. Prototype methods to this generator, for context-sensitive actions per data object.
Data Object:
- Adds
.parent- Object, The data objectIndicates when the value of this data object is an array. - Adds
.children- Array, Contains any and all data objects derived from this value. - Adds
.childIndex- Integer, The index of this data object within it's parent's.childrenarray. - Adds
.nextSibling- Object, References the data object following this one, within the parent's.childrenarray. - Adds
.previousSibling- Object, References the data object preceding this one, within the parent's.childrenarray. - Adds
.firstChild- Object, References the first data object within the.childrenarray. - Adds
.lastChild- Object, References the last data object within the.childrenarray.
var genRelations = genData.spawn(function (name, value, parent) {
var data = this;
data.parent = parent;
data.children = [];
if (parent) {
if (parent.children.length) {
data.previousSibling = parent.children[parent.children.length - 1];
data.previousSibling.nextSibling = data;
} else {
parent.firstChild = data;
}
data.childIndex = parent.children.push(data);
parent.lastChild = data;
}
});by bemson
Avoids an infinite loop when iterating over a recursive object. A data object is created for reoccurring object references, but their value is not scanned for further properties.
Data Object:
- Adds
.reoccurs- Integer, A zero-based identifier, shared by other data objects which reference the same recursive value. When 0, the data object's value does not reoccur within the dataset.
Requires:
- JavaScript engine implementing
Array.indexOf().
var genNoRecursion = genData.spawn(function (name, value, parent, dataset, flags, shared) {
if (!shared.foundRefs) {
shared.foundRefs = [];
shared.foundData = [];
}
this.reoccurs = 0;
if (typeof value === 'object') {
var existingIndex = shared.foundRefs.indexOf(value);
if (~existingIndex) {
flags.scan = 0;
this.reoccurs = shared.foundData[existingIndex].reoccurs = existingIndex + 1;
} else {
shared.foundRefs.push(value);
shared.foundData.push(this);
}
}
});by bemson
Returns data objects that reference and represent a UL tree-menu. The first dataset object's .menuElement property is the root UL node of the menu.
Data Object:
- Adds
.itemElement- Node, The LI node for this data object. - Adds
.anchorElement- Node, The A node for this data object. This property is added when the data object's value is a string, or when the value has a member-property named "_url". - Adds
.menuElement- Node, The UL node for this data object. This property is added when the data object's value creates child objects.
var genMenu = genData.spawn(function (name, value, parent, dataset, flags) {
if (name === '_url') {
flags.omit = 1;
} else {
this.itemElement = document.createElement('li');
this.itemUrl = typeof value === 'string' ? value : value._url;
if (this.itemUrl) {
this.anchorElement = document.createElement('a');
this.anchorElement.appendChild(document.createTextNode(this.name));
this.anchorElement.href = this.itemUrl;
this.itemElement.appendChild(this.anchorElement);
} else {
this.itemElement.appendChild(document.createTextNode(this.name));
}
if (parent) {
if (!parent.menuElement) {
parent.menuElement = parent.itemElement.appendChild(document.createElement('ul'));
parent.itemElement.className = 'isMenu';
}
parent.menuElement.appendChild(this.itemElement);
}
}
});Here we create a UL menu from an object literal, using genMenu(). The first object in the returned dataset will have a .menuElement property that contains the UL node for the menu. We could then append this node somewhere in the page DOM.
var treeMap = {
home: 'home.html',
about: {
_url: 'about.html',
staff: 'staff.html',
location: 'location.html'
},
services: {
_url: 'services.html',
exports: 'exports.html',
imports: 'imports.html',
sales: 'sales.html'
}
},
menuSet = genMenu(treeMap);
// add the first ul node to the dom
document.body.appendChild(menuSet[0].menuElement);Custom generators return arrays with variable content. Often these generators do not return data objects, but an object that was either created or filtered from the original value.
- grepFncs - Returns an array of found functions.
- mapObject - Returns an array of values from applying values to a function.
- flattenArray - Returns an array of elements, from nested arrays.
- getValuesWithKey - Filters object properties who's key matches the given needle.
by bemson
Returns an array of found functions.
var grepFncs = genData.spawn(function (name, value, parent, dataset, flags) {
flags.omit = 1;
if (typeof value === 'function') {
dataset.push(value);
}
});by bemson
Returns an array of values from applying values to a function. Returns nothing when the first child is not a function.
var mapObject = genData.spawn(function (name, value, parent, dataset, flags, shared) {
flags.omit = 1;
if (parent) {
if (!shared.mapFunction) {
if (typeof value === 'function') {
shared.mapFunction = value;
} else {
flags.exit = 1;
}
} else if (!shared.inArrayToMap) {
shared.inArrayToMap = 1;
shared.idx = 0;
} else {
flags.scan = 0;
dataset.push(shared.mapFunction(value, shared.idx++));
}
}
});by bemson
Returns an array of elements, from nested arrays. Arrays within objects are not flattened.
var flattenArray = genData.spawn(function (name, value, parent, dataset, flags) {
flags.omit = 1;
if (!~{}.toString.call(value).indexOf('y')) {
flags.scan = 0;
dataset.push(value);
}
});by bemson
Filters object properties who's key matches the given needle. The needle may be a string, regular expression or function (to test the data's name). Matches properties are not further scanned.
var getValuesWithKey = genData.spawn(function (name, value, parent, dataset, flags, shared) {
flags.omit = 1;
if (shared.parsedArgs) {
if (shared.findFnc(name)) {
dataset.push(value);
flags.scan = 0;
}
} else if (parent) {
shared.parsedArgs = 1;
switch (typeof value) {
case 'function' :
shared.findFnc = value;
break;
case 'string' :
shared.findFnc = function (hay) {
return ~hay.indexOf(value);
};
break;
case 'object' :
if (value.constructor === RegExp) {
shared.findFnc = function (hay) {
return value.test(hay);
};
}
break;
}
if (!shared.findFnc) {
flags.exit = 1;
}
}
});===
If you'd like to share your generator here, send me a message on github! Your generator may use an existing name and reference your favorite library. Licensing is not allowed, but your name will be noted in the description.