indexed-set.js
A utility wrapper for set operations using arrays of objects. Work with sets as if they were simple arrays! Updated for ES6 proxies( For Harmony Proxies, please use <= 1.x).
Each set has a chain of ancestry which, at it's root, is a collection. All values are held in the collections, while the sets themselves are simply orderings across subsets of ids
Instantiating
First, require the module:
const { Indexed } = require('indexed-set');
// or
const { IndexedSet } = require('indexed-set');
const Indexed = IndexedSet.enableProxyWrapper();
// or
import { Indexed } from 'indexed-set';
// or
import { IndexedSet } from 'indexed-set';
const Indexed = IndexedSet.enableProxyWrapper();
Then create a collection:
const collection = new Indexed.Collection(<array>, [<keyName>]);
where keyName defaults to Mongo's '_id' or
var collection = new Indexed.Collection(<options>);
The available options are:
- datasource : the mongo adapter
- name : the name of the collection to load
- onLoad : executed when the collection load is complete
then to create a set:
new Indexed.Set(collection);
Internal Data Access
- getByPosition(position) : retrieve the object by the position of the object within the set
- getById(id) : retrieve the object by it's primary key within the set
- setByIdFromString(id, idString) : substitue the object with id idString for the position of the passed id
- setByPositionFromString(position, idString) : substitue the object with id idString for the passed position
- setByIdFromObject(id, object) : substitue this object at the position of the object with the passed in id
- setByPositionFromObject(position, object) : substitue this object at the position provided
additionally you are able to call:
Indexed.enableProxyWrapper();
which wraps a proxy around the object so you can use an array-like syntax:
so given a set:
var collection = new Indexed.Collection([
{a:'a',b:'b',c:'c'},
{a:'d',b:'e',c:'f'},
{a:'r',b:'q',c:'f'}
], 'a');
var mySet = new Indexed.Set(collection);
I could say:
mySet['a']
which resolves to:
{a:'a',b:'b',c:'c'}
as does
mySet.by.position[0]
and, as another example:
mySet['r']
is
{a:'r',b:'q',c:'f'}
Meaning you can either address by primary key or position.
Array Syntax
The Set class implements a number of the standard array methods, for familiarity
- indexOf(object)
- forEach(iteratorFunction)
- push(object)
- pop()
- shift()
- slice(start, [stop]) : take a subset by index range
Set Functions
This is the meat of the library allowing you to manipulate and analyze datasets while still staying economical with memory and performance.
- and(set) : the union of all objects in both sets
- or(set) : all objects in either set
- xor(set) : all objects contained in one set, but not both
- not(set) : all objects not present in 'set'
- filter(filterFunction) : a filter passed across the set to determine if a given element is selected or not
- with(field, comparison, value) : a convenience method to generate a filter
- byGroup(field) : segment along a given field and bin objects by the value on that field. returns an object of arrays
- distinct([field]) : return all potential values for a given field, or if none is provided, provide all options for all fields, broken down by field.
- clone() : make a copy of the set (this is a relatively cheap operation, in comparison to many clone() functions)
- resume() : allow filters to execute as they are applied (started by default), also executes queued filters
- pause() : queue applied filters instead of immediately executing them.
- filterFunction() : return a function which is a composite of all filter functions on this set(can be passed to mongo as a selector function).
- hierarchy(hierarchies, [fields]) : the tree of dependencies by node based on the descending relationships (provided an array of arrays of fieldNames). This produces overlapping relationship trees based on the passed priority. I won't go into further detail because this is a CPU bound task. If you don't know how to compensate for that, avoid the feature, lest you have unresponsive services.
- aggregate(field, [aggregatorFn]) : aggregate all set members on a given field, default aggregation is just a = a + b.
Proxy Suport
All modern JS environments support the Proxy object, but if you need to support older node versions that do not:
npm install --save node-proxy
if(!global.Proxy) global.Proxy = require('node-proxy');
Testing
Run the test harness at the project root with:
mocha
Enjoy,
-Abbey Hawk Sparrow