Skip to content
This repository has been archived by the owner on Sep 13, 2019. It is now read-only.

Commit

Permalink
Merge pull request #23 from Floofies/master
Browse files Browse the repository at this point in the history
Fixing readme errors, adding docs to src
  • Loading branch information
Floofies authored Oct 18, 2017
2 parents d86f437 + 461c8cd commit 3fa2202
Show file tree
Hide file tree
Showing 3 changed files with 132 additions and 16 deletions.
8 changes: 4 additions & 4 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand All @@ -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`

Expand All @@ -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
Expand Down
13 changes: 6 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -597,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.

Expand Down Expand Up @@ -630,7 +629,7 @@ var subject = {
]
};

var path = differentia.pathfind(subject, "Little Trees");
var path = differentia.pathFind(subject, "Little Trees");

console.log(path);
/* Logs:
Expand Down
127 changes: 122 additions & 5 deletions src/differentia.js
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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.
Expand All @@ -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);
Expand Down Expand Up @@ -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, {
Expand Down Expand Up @@ -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)) {
Expand Down Expand Up @@ -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, {
Expand All @@ -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, {
Expand All @@ -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, {
Expand All @@ -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, {
Expand All @@ -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, {
Expand All @@ -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, {
Expand All @@ -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, {
Expand All @@ -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, {
Expand All @@ -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, {
Expand All @@ -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, {
Expand All @@ -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, {
Expand All @@ -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, {
Expand Down

0 comments on commit 3fa2202

Please sign in to comment.