From 879254e519de5f1c9819cd8b78c189d1d3770a38 Mon Sep 17 00:00:00 2001 From: Floofies Date: Wed, 11 Oct 2017 18:33:18 -0400 Subject: [PATCH 1/4] Minor refinements, typo fixes --- README.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index facd92e..1b19a32 100644 --- a/README.md +++ b/README.md @@ -54,8 +54,7 @@ Property|Datatype|Description accessor|Mixed|The accessor being used to access `value.tuple.subject` during property/element enumerations. Equal to `state.accessors[state.iteration]`. accessors|Array|An Array of enumerable acessors found in `value.tuple.search`. currentValue|Mixed|The value of the element of enumeration. Equal to `value.tuple.subject[value.accessor]`. -existing|`null` or Object|If `dfs` encounters an Object/Array it has been before during the same search, this property will be set to the equivalent tuple; otherwise it will be `null`. Objects added to that tuple previously will show up again here. -isArray|Boolean|Indicates if the Object being traversed/enumerated is an Array. +existing|`null` or Object|If `dfs` encounters an Object/Array it has seen before during the same search, this property will be set to the equivalent tuple; otherwise it will be `null`. Objects added to that tuple previously will show up again here. isContainer|Boolean|Indicates if the current item of the enumeration is an Object or Array. isFirst|Boolean|Indicates if the current item of the enumeration is the first item to be enumerated. isLast|Boolean|Indicates if the current item of the enumeration is the last item to be enumerated. @@ -401,7 +400,7 @@ Variable `clonedObject` is now this Object: ```JavaScript diff( subject , compared [, search = null ] ); ``` -Returns `true` if any of `compared`'s properties differ in any way from `subject`, or `false` if otherwsie. +Returns `true` if `compared`'s structure, properties, or values differ in any way from `subject`, or `false` if otherwsie. #### Parameters - **`subject`** Object/Array From ee4ae2fa09ce5548a7e9b606a0abf6f4a0d060ae Mon Sep 17 00:00:00 2001 From: Floofies Date: Wed, 11 Oct 2017 18:33:44 -0400 Subject: [PATCH 2/4] Added docs for all strategies --- src/differentia.js | 127 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 122 insertions(+), 5 deletions(-) diff --git a/src/differentia.js b/src/differentia.js index fb64f85..2f2820d 100755 --- a/src/differentia.js +++ b/src/differentia.js @@ -288,7 +288,7 @@ var differentia = (function () { } } } - /** + /** * dfs - A thunk to `searchIterator`, providing a Stack for target nodes. * Causes `seatchIterator` to behave as Depth-First Search. * @param {Object|Array} subject The Object/Array to access. @@ -298,7 +298,7 @@ var differentia = (function () { function dfs(subject, search = null) { return searchIterator(subject, new Stack(), search); } - /** + /** * bfs - A thunk to `searchIterator`, providing a Queue for target nodes. * Causes `seatchIterator` to behave as Breadth-First Search. * @param {Object|Array} subject The Object/Array to access. @@ -311,10 +311,10 @@ var differentia = (function () { /** * runStrategy - Calls `strategy.entry` and `strategy.main` with the state of the search iterator. * `strategy.entry` is optional. It is only executed once, for the first value the iterator yields. - * @param {Object} strategy An Object containing an optional `entry` property and a required `main` property. + * @param {Object} strategy An Object containing an optional `entry` property and a required `main` property. * @param {Generator} searchAlg A Generator to use as the search algorthm. - * @param {Object} parameters An Object containing a required `subject` property, and an optional `search` property. - * @returns {Mixed} Returns anything `strategy.main` returns. + * @param {Object} parameters An Object containing a required `subject` property, and an optional `search` property. + * @returns {Mixed} Returns anything `strategy.main` returns. */ function runStrategy(strategy, searchAlg, parameters) { assert.object(strategy, 1); @@ -343,6 +343,12 @@ var differentia = (function () { } } const strategies = {}; + /** + * clone - Creates a deep clone of `subject`. + * @param {Object|Array} subject The Object/Array to clone. + * @param {Object|Array|null} [search = null] An optional search index, acting as a traversal whitelist. + * @returns {Object|Array} A clone of `subject`. + */ strategies.clone = { interface: function (subject, search = null) { return runStrategy(strategies.clone, dfs, { @@ -385,6 +391,13 @@ var differentia = (function () { } } }; + /** + * diff - Determines if `compared`'s structure, properties, or values differ in any way from `subject` + * @param {Object|Array} subject The first Object/Array to compare. + * @param {Object|Array} compare The second Object/Array to compare. + * @param {Object|Array|null} [search = null] An optional search index, acting as a traversal whitelist. + * @returns {Boolean} Indicates if a difference was found. + */ strategies.diff = { interface: function (subject, compare, search = null) { if (search === null && getContainerLength(subject) !== getContainerLength(compare)) { @@ -430,6 +443,13 @@ var differentia = (function () { } } }; + /** + * diffClone - Clones the parts of `subject` that differ from `compared`'s structure, properties, or values. + * @param {Object|Array} subject The first Object/Array to compare and also clone. + * @param {Object|Array} compare The second Object/Array to compare. + * @param {Object|Array|null} [search = null] An optional search index, acting as a traversal whitelist. + * @returns {Object|Array} A clone of `subject`, only including differences. + */ strategies.diffClone = { interface: function (subject, compare, search = null) { return runStrategy(strategies.diffClone, dfs, { @@ -448,6 +468,12 @@ var differentia = (function () { } } }; + /** + * deepFreeze - Freezes all objects found in `subject`. + * @param {Object|Array} subject The Object/Array to deeply freeze. + * @param {Object|Array|null} [search = null] An optional search index, acting as a traversal whitelist. + * @returns {Object|Array} The original `subject`. + */ strategies.deepFreeze = { interface: function (subject, search = null) { return runStrategy(strategies.deepFreeze, dfs, { @@ -467,6 +493,12 @@ var differentia = (function () { } } }; + /** + * deepSeal - Seal all objects found in `subject`. + * @param {Object|Array} subject The Object/Array to deeply seal. + * @param {Object|Array|null} [search = null] An optional search index, acting as a traversal whitelist. + * @returns {Object|Array} The original `subject`. + */ strategies.deepSeal = { interface: function (subject, search = null) { return runStrategy(strategies.deepSeal, dfs, { @@ -486,6 +518,17 @@ var differentia = (function () { } } }; + /** + * forEach - A simple IOC wrapper to the `dfs` search iterator. + * @param {Object|Array} subject The Object/Array to traverse/enumerate. + * @param {callback} callback The function to invoke per-property of all objects in `subject`. + * @callback callback + * @param {Mixed} value Equal to `subject[accessor]`. + * @param {Mixed} accessor Used to access `subject`. + * @param {Object|Array} subject The Object/Array being travered/enumerated. + * @param {Object|Array|null} [search = null] An optional search index, acting as a traversal whitelist. + * @returns {Mixed} Will return anything `callback` returns. + */ strategies.forEach = { interface: function (subject, callback, search = null) { return runStrategy(strategies.forEach, dfs, { @@ -498,6 +541,17 @@ var differentia = (function () { return state.parameters.callback(state.currentValue, state.accessor, state.tuple.subject); } }; + /** + * find - Returns a value if it passes the test, otherwise returns `undefined`. + * @param {Object|Array} subject The Object/Array to traverse/enumerate. + * @param {callback} callback Must return `true` if value passes the test. + * @callback callback + * @param {Mixed} value Equal to `subject[accessor]`. + * @param {Mixed} accessor Used to access `subject`. + * @param {Object|Array} subject The Object/Array being travered/enumerated. + * @param {Object|Array|null} [search = null] An optional search index, acting as a traversal whitelist. + * @returns {Boolean} A value that passes the test in `callback`. + */ strategies.find = { interface: function (subject, callback, search = null) { return runStrategy(strategies.find, dfs, { @@ -512,6 +566,17 @@ var differentia = (function () { } } }; + /** + * some - Returns `true` if at least one value passes the test, otherwise returns `false`. + * @param {Object|Array} subject The Object/Array to traverse/enumerate. + * @param {callback} callback Must return `true` if value passes the test. + * @callback callback + * @param {Mixed} value Equal to `subject[accessor]`. + * @param {Mixed} accessor Used to access `subject`. + * @param {Object|Array} subject The Object/Array being travered/enumerated. + * @param {Object|Array|null} [search = null] An optional search index, acting as a traversal whitelist. + * @returns {Boolean} Indicates if at least one value passed the test. + */ strategies.some = { interface: function (subject, callback, search = null) { return runStrategy(strategies.some, dfs, { @@ -529,6 +594,17 @@ var differentia = (function () { } } }; + /** + * every - Returns `true` if all values passes the test, otherwise returns `false`. + * @param {Object|Array} subject The Object/Array to traverse/enumerate. + * @param {callback} callback Must return `true` if value passes the test. + * @callback callback + * @param {Mixed} value Equal to `subject[accessor]`. + * @param {Mixed} accessor Used to access `subject`. + * @param {Object|Array} subject The Object/Array being travered/enumerated. + * @param {Object|Array|null} [search = null] An optional search index, acting as a traversal whitelist. + * @returns {Boolean} Indicates if all values passed the test. + */ strategies.every = { interface: function (subject, callback, search = null) { return runStrategy(strategies.every, dfs, { @@ -546,6 +622,17 @@ var differentia = (function () { } } }; + /** + * map - Clones the parts of `subject` which pass the test. + * @param {Object|Array} subject The Object/Array to traverse/enumerate. + * @param {callback} callback Must return `true` if value passes the test. + * @callback callback + * @param {Mixed} value Equal to `subject[accessor]`. + * @param {Mixed} accessor Used to access `subject`. + * @param {Object|Array} subject The Object/Array being travered/enumerated. + * @param {Object|Array|null} [search = null] An optional search index, acting as a traversal whitelist. + * @returns {Object|Array} A clone of `subject`, only containing values which pass the test. + */ strategies.map = { interface: function (subject, callback, search = null) { return runStrategy(strategies.map, dfs, { @@ -566,6 +653,12 @@ var differentia = (function () { } } }; + /** + * paths - Creates a record of the tree paths present within `subject`. + * @param {Object|Array} subject The Object/Array to record paths of. + * @param {Object|Array|null} [search = null] An optional search index, acting as a traversal whitelist. + * @returns {Array} An array containing arrays, each representing nodes in a path. + */ strategies.paths = { interface: function (subject, search = null) { return runStrategy(strategies.paths, bfs, { @@ -590,6 +683,12 @@ var differentia = (function () { } } }; + /** + * pathFind - Creates a record of the tree path to `findValue` if found within `subject`, or returns `null`. + * @param {Object|Array} subject The Object/Array to search for `findValue`. + * @param {Object|Array|null} [search = null] An optional search index, acting as a traversal whitelist. + * @returns {Array|null} An array containing arrays, each representing nodes in a path. + */ strategies.pathFind = { interface: function (subject, findValue, search = null) { return runStrategy(strategies.pathFind, bfs, { @@ -610,6 +709,13 @@ var differentia = (function () { } } }; + /** + * diffPaths - Creates a record of tree paths in `subject` which differ from the tree paths of `compare`. + * @param {Object|Array} subject The first Object/Array to compare, and record paths from. + * @param {Object|Array} compare The second Object/Array to compare. + * @param {Object|Array|null} [search = null] An optional search index, acting as a traversal whitelist. + * @returns {Array} An array containing arrays, each representing nodes in a path. + */ strategies.diffPaths = { interface: function (subject, compare, search = null) { return runStrategy(strategies.diffPaths, bfs, { @@ -634,6 +740,17 @@ var differentia = (function () { } } }, + /** + * filter - Clones the parts of `subject` which pass the test. + * @param {Object|Array} subject The Object/Array to traverse/enumerate. + * @param {callback} callback Must return `true` if value passes the test. + * @callback callback + * @param {Mixed} value Equal to `subject[accessor]`. + * @param {Mixed} accessor Used to access `subject`. + * @param {Object|Array} subject The Object/Array being travered/enumerated. + * @param {Object|Array|null} [search = null] An optional search index, acting as a traversal whitelist. + * @returns {Object|Array} A clone of `subject`, only containing values which pass the test. + */ strategies.filter = { interface: function (subject, callback, search = null) { return runStrategy(strategies.filter, bfs, { From c8fc311680a867c4557f9f9fc6ff84eee09951de Mon Sep 17 00:00:00 2001 From: Floofies Date: Wed, 11 Oct 2017 18:39:59 -0400 Subject: [PATCH 3/4] Updated refs to search algorithms --- CONTRIBUTING.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0ef8613..19c745e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -23,7 +23,7 @@ Creates a `prod-build` directory to build the production release into. Saves `sr Add `clean` at the end to remove `node_modules`. # Adding Algorithms -To add an algorithm to the library, you must use the Strategy Pattern together with `runStrategy`, which is the primary gateway for your algorithms to interact with and use the `iddfs` iterator. Your algorithm will be tightly coupled to the the `iddfs` iterator, and you should make use of one of the many properties made available through it's `state` object. An algorithm may "steer" the search algorithm by directly mutating certain properties of `state`. See documentation for `iddfs` in `README.md` for more information. +To add an algorithm to the library, you must use the Strategy Pattern together with `runStrategy`, which is the primary gateway for your algorithms to interact with a search iterator. Your algorithm will be tightly coupled to `searchIterator`, and you should make use of one of the many properties made available through it's shared state object. An algorithm may "steer" the search algorithm by directly mutating certain properties of `state`. See documentation for *Search Algorithm Iterators* in `README.md` for more information. All strategies added to the `strategies` object will be automatically revealed to the end-user via their `interface` properties. Once you add a strategy, you should also include it's name in `spec/Spec.js` in the first unit test, as part of the `modules` array; the test will verify that your strategy is accessible. @@ -48,11 +48,11 @@ Property|Data Type|Description `entry`|Function|(*Optional*) A Call-With-Current-State callback to run with the first iterator state, only once. This function cannot return values. `main`|Function|A Call-With-Current-State callback to run on every iteraton. If this function returns something other than `undefined`, it will be returned to the user's caller. -`entry` and `main` recieve a single `state` argument, the iterator state flyweight Object, which is a single object the iterator actively mutates per-iteration. See documentation for `iddfs` in `README.md` for more information. +`entry` and `main` recieve a single `state` argument, the iterator state flyweight Object, which is a single object the iterator actively mutates per-iteration. See documentation for *Search Algorithm Iterators* in `README.md` for more information. --- -Your Strategy's `interface` function must call `runStrategy` to use the `iddfs` iterator: +Your Strategy's `interface` function must call `runStrategy` to use search iterators: ### `runStrategy` @@ -62,7 +62,7 @@ runStrategy( strategy, searchAlg, parameters ); ``` An IOC wrapper for Generators/Iterators. `runStrategy` advances the iterator returned by `searchIterator` and executes Call-With-Current-State functions supplied in `strategy`. The state flyweight object is passed to `strategy.main`, which is executed for each element, and `strategy.entry`, which is only executed for the first element. If `strategy.main` returns something other than `undefined`, it will be returned to the caller. -`searchAlg` is the search algorithm Generator to use; it can be `dfs` or `bfs`, or any Generator. +`searchAlg` is the search algorithm iterator to use; it can be `dfs` or `bfs`, or any Generator. #### Parameters - **`strategy`** Object From 461c8cdeab252a52fd72d5197fa11bc3aa394838 Mon Sep 17 00:00:00 2001 From: Floofies Date: Wed, 18 Oct 2017 15:32:50 -0400 Subject: [PATCH 4/4] Minor fixes --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 1b19a32..6e4b919 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ This library provides a basic suite of Object/Array focused functions. They are - [deepFreeze](#deepfreeze) - [deepSeal](#deepseal) - [paths](#paths) - - [pathfind](#pathfind) + - [pathFind](#pathfind) - [diffpaths](#diffpaths) - [Higher-Order Functions](#higher-order-functions) - [forEach](#foreach) @@ -596,11 +596,11 @@ console.log(paths); ___ -### `pathfind` +### `pathFind` *Function* ```JavaScript -pathfind( subject, findValue [, search = null ] ); +pathFind( subject, findValue [, search = null ] ); ``` Traverses and enumerates `subject`, searching for `findValue`. Returns an Array containing the path of `findValue`, or `null` if it was not found. @@ -629,7 +629,7 @@ var subject = { ] }; -var path = differentia.pathfind(subject, "Little Trees"); +var path = differentia.pathFind(subject, "Little Trees"); console.log(path); /* Logs: