Comparing version 0.2.0 to 0.2.2
{ | ||
"name": "qintervals", | ||
"version": "0.2.0", | ||
"version": "0.2.2", | ||
@@ -5,0 +5,0 @@ "description": "A JavaScript library allowing to store and manipulate lists of intervals.", |
@@ -122,3 +122,3 @@ // QIntervals <https://github.com/jshq/qintervals> | ||
it("should test union functionality.", function() { | ||
it("should test union functionality #1.", function() { | ||
var a = [0, 1, 10, 11, 20, 21]; | ||
@@ -149,3 +149,13 @@ var b = [1, 2, 11, 12, 21, 22]; | ||
it("should test intersect functionality.", function() { | ||
it("should test union functionality #2.", function() { | ||
var a = qintervals(); | ||
a.union([0, 1]); | ||
assert(a.equals([0, 1])); | ||
a.union([1, 2]); | ||
assert(a.equals([0, 2])); | ||
}); | ||
it("should test intersect functionality #1.", function() { | ||
var a = [0, 2, 10, 12, 20, 22]; | ||
@@ -177,2 +187,9 @@ var b = [1, 3, 11, 13, 21, 23]; | ||
it("should test intersect functionality #2.", function() { | ||
var a = qintervals([0, 9]); | ||
a.intersect([0, 1, 5, 9]); | ||
assert(a.equals([0, 1, 5, 9])); | ||
}); | ||
it("should test xor functionality.", function() { | ||
@@ -179,0 +196,0 @@ var a = [0, 1, 2, 3, 4, 5, 6, 7]; |
@@ -12,10 +12,8 @@ // QIntervals <https://github.com/jshq/qintervals> | ||
/** | ||
* qintervals(arg) | ||
* | ||
* Preferred constructor to create a new `qintervals` instance based on `arg`, | ||
* which can be a list of packed intervals or objects. | ||
* | ||
* If no argument is provided an empty instance of `qintervals` is returned. | ||
*/ | ||
// \function `qintervals(arg)` | ||
// | ||
// Preferred constructor to create a new `qintervals` instance based on `arg`, | ||
// which can be a list of packed intervals or objects. | ||
// | ||
// If no argument is provided an empty instance of `qintervals` is returned. | ||
function qintervals(arg, aKey, bKey) { | ||
@@ -37,33 +35,25 @@ var data = null; | ||
/** | ||
* qintervals.VERSION | ||
* | ||
* Version string of `qintervals` library as "major.minor.patch". | ||
*/ | ||
// \def `qintervals.VERSION` | ||
// | ||
// Version string of `qintervals` library as "major.minor.patch". | ||
qintervals.VERSION = "0.2.0"; | ||
/** | ||
* qintervals.kTestNone | ||
* | ||
* A testing value of an interval didn't hit the list of intervals. | ||
*/ | ||
// \def `qintervals.kTestNone` | ||
// | ||
// A testing value of an interval didn't hit the list of intervals. | ||
qintervals.kTestNone = kTestNone; | ||
/** | ||
* qintervals.kTestFull | ||
* | ||
* A testing value of an interval fully hits the list of intervals. | ||
*/ | ||
// \def `qintervals.kTestFull` | ||
// | ||
// A testing value of an interval fully hits the list of intervals. | ||
qintervals.kTestFull = kTestFull; | ||
/** | ||
* qintervals.kTestPart | ||
* | ||
* A testing value of an interval partially hits the list of intervals. | ||
*/ | ||
// \def `qintervals.kTestPart` | ||
// | ||
// A testing value of an interval partially hits the list of intervals. | ||
qintervals.kTestPart = kTestPart; | ||
/** | ||
* Autodetect a property contained in `obj` based on the property `list`. | ||
*/ | ||
// \internal | ||
// | ||
// Autodetect a property contained in `obj` based on the property `list`. | ||
function detectKey(obj, list) { | ||
@@ -79,9 +69,8 @@ for (var i = 0, len = list.length; i < len; i++) { | ||
} | ||
var DetectFrom = ["from", "start", "a"]; | ||
var DetectTo = ["to" , "end" , "b"]; | ||
var detectFrom = ["from", "start", "a"]; | ||
var detectTo = ["to" , "end" , "b"]; | ||
/** | ||
* Equality check. | ||
*/ | ||
// \internal | ||
// | ||
// Equality check. | ||
function equals(a, b) { | ||
@@ -102,11 +91,11 @@ var aLen = a.length; | ||
/** | ||
* Get whether `data` is a well-formed list of intervals | ||
* | ||
* Well format means: | ||
* | ||
* - Intervals are sorted. | ||
* - Intervals don't intersect. | ||
* - Intervals are incontinuous, i.e. [1, 3] instead of [1, 2, 2, 3]. | ||
*/ | ||
// \internal | ||
// | ||
// Get whether `data` is a well-formed list of intervals | ||
// | ||
// Well-formed means: | ||
// | ||
// - Intervals are sorted. | ||
// - Intervals don't intersect. | ||
// - Intervals are incontinuous, i.e. [1, 3] instead of [1, 2, 2, 3]. | ||
function isWellFormed(data) { | ||
@@ -137,8 +126,8 @@ var len = data.length; | ||
/** | ||
* Get well-formed data. | ||
* | ||
* Returns an array of well-formed data that can be same as `data` passed in | ||
* case that intervals inside are sorted, don't intersect, and are coalesced. | ||
*/ | ||
// \internal | ||
// | ||
// Get well-formed data. | ||
// | ||
// Returns an array of well-formed data that can be same as `data` passed in | ||
// case that intervals inside are sorted, don't intersect, and are coalesced. | ||
function asWellFormed(data) { | ||
@@ -214,5 +203,5 @@ if (isWellFormed(data)) | ||
/** | ||
* Get well-formed data based on data containing interval objects. | ||
*/ | ||
// \internal | ||
// | ||
// Get well-formed data based on data containing interval objects. | ||
function asWellFormedFromObjects(data, aKey, bKey) { | ||
@@ -231,4 +220,4 @@ var len = data.length; | ||
if (!aKey) aKey = detectFrom[0]; | ||
if (!bKey) bKey = detectTo[0]; | ||
if (!aKey) aKey = DetectFrom[0]; | ||
if (!bKey) bKey = DetectTo[0]; | ||
@@ -238,4 +227,4 @@ for (var i = 0; i < len; i++) { | ||
if (!hasOwnProperty.call(obj, aKey)) aKey = detectKey(obj, detectFrom); | ||
if (!hasOwnProperty.call(obj, bKey)) bKey = detectKey(obj, detectTo); | ||
if (!hasOwnProperty.call(obj, aKey)) aKey = detectKey(obj, DetectFrom); | ||
if (!hasOwnProperty.call(obj, bKey)) bKey = detectKey(obj, DetectTo); | ||
@@ -296,18 +285,18 @@ a = obj[aKey]; | ||
/** | ||
* Return `qintervals` object reusing an array of packed intervals. | ||
* | ||
* NOTE: This is a low-level function that just wraps a given `array` to be used | ||
* by `qintervals` object, it doesn't copy the values if they are well format | ||
* (sorted, coalesced, and non-intersecting). | ||
*/ | ||
// \function `qintervals.wrap(data)` | ||
// | ||
// Return `qintervals` object reusing/wrapping an existing array of packed intervals. | ||
// | ||
// NOTE: This is a low-level function that just wraps a given `array` to be used | ||
// by `qintervals` object, it doesn't copy the values if they are well-formed | ||
// (sorted, coalesced, and non-intersecting). | ||
function wrap(data) { | ||
return new qintervals(asWellFormed(data)); | ||
} | ||
qintervals.wrap = wrap; | ||
/** | ||
* Incrementally merge (union operation) multiple arrays passed in `arrays`. | ||
* | ||
* Returns a single array containing all intervals merged and coalesced. | ||
*/ | ||
// \internal | ||
// | ||
// Incrementally merge (union operation) multiple arrays passed in `arrays`. | ||
// Returns a single array containing all intervals merged and coalesced. | ||
function mergeArrays(arrays) { | ||
@@ -350,5 +339,5 @@ var len = arrays.length; | ||
/** | ||
* Append `b` to `a` starting at `offset`. | ||
*/ | ||
// \internal | ||
// | ||
// Append `b` to `a` starting at `offset`. | ||
function append(a, b, offset) { | ||
@@ -363,5 +352,5 @@ var i = offset || 0; | ||
/** | ||
* Find an index that is closest to `value`. | ||
*/ | ||
// \internal | ||
// | ||
// Find an index that is closest to `value`. | ||
function closestIndex(data, value) { | ||
@@ -398,5 +387,5 @@ // Should always be 2 or greater. | ||
/** | ||
* Get whether interval `data` contains value or interval `value`. | ||
*/ | ||
// \internal | ||
// | ||
// Get whether interval `data` contains value or interval `value`. | ||
function testOp(a, value) { | ||
@@ -473,5 +462,5 @@ var aLen = a.length; | ||
/** | ||
* Return a new array that contains `a` shifted by a scalar value `b`. | ||
*/ | ||
// \internal | ||
// | ||
// Return a new array that contains `a` shifted by a scalar value `b`. | ||
function shiftOp(data, value) { | ||
@@ -503,5 +492,5 @@ var output = []; | ||
/** | ||
* Return a new array that contains `a` OR `b`. | ||
*/ | ||
// \internal | ||
// | ||
// Return a new array that contains `a` OR `b`. | ||
function orOp(a, b) { | ||
@@ -562,5 +551,5 @@ var output = []; | ||
/** | ||
* Return a new array that contains `a` AND `b`. | ||
*/ | ||
// \internal | ||
// | ||
// Return a new array that contains `a` AND `b`. | ||
function andOp(a, b) { | ||
@@ -634,5 +623,5 @@ var output = []; | ||
/** | ||
* Return a new array that contains `a` XOR `b`. | ||
*/ | ||
// \internal | ||
// | ||
// Return a new array that contains `a` XOR `b`. | ||
function xorOp(a, b) { | ||
@@ -734,5 +723,5 @@ var output = []; | ||
/** | ||
* Return a new array that contains `a` SUB `b`. | ||
*/ | ||
// \internal | ||
// | ||
// Return a new array that contains `a` SUB `b`. | ||
function subOp(a, b) { | ||
@@ -816,5 +805,5 @@ var output = []; | ||
/** | ||
* Get well-formed data of `arg`. | ||
*/ | ||
// \internal | ||
// | ||
// Get well-formed data of `arg`. | ||
function dataFromArg(arg, aKey, bKey) { | ||
@@ -843,5 +832,5 @@ if (arg instanceof qintervals) | ||
/** | ||
* Special case, which results in merging two lists of intervals. | ||
*/ | ||
// \internal | ||
// | ||
// Special case, which results in merging two lists of intervals. | ||
function mergeOp(a, b) { | ||
@@ -864,2 +853,3 @@ var aLen = a.length; | ||
var b0 = b[0]; | ||
var b1 = b[bLen - 1]; | ||
var a1 = a[aLen - 1]; | ||
@@ -883,6 +873,4 @@ | ||
// Prepend. | ||
var a0 = a[0]; | ||
var b1 = b[bLen - 1]; | ||
// Prepend. | ||
if (a0 >= b1) { | ||
@@ -907,5 +895,5 @@ // Merge last `b` interval with first `a` interval. | ||
/** | ||
* Special case, which results in clearing two lists of intervals. | ||
*/ | ||
// \internal | ||
// | ||
// Special case, which results in clearing two lists of intervals. | ||
function clearOp(a, b) { | ||
@@ -915,5 +903,5 @@ return (a.length === 0) ? a : []; | ||
/** | ||
* Special case, which results in keeping the original list of intervals as is. | ||
*/ | ||
// \internal | ||
// | ||
// Special case, which results in keeping the original list of intervals as is. | ||
function noOp(a, b) { | ||
@@ -923,5 +911,5 @@ return a; | ||
/** | ||
* Member operation (builder). | ||
*/ | ||
// \internal | ||
// | ||
// Member operation (builder). | ||
function memberOp(regularFn, specialFn) { | ||
@@ -951,5 +939,5 @@ return function() { | ||
/** | ||
* Static operation (builder). | ||
*/ | ||
// \internal | ||
// | ||
// Static operation (builder). | ||
function staticOp(fn) { | ||
@@ -968,17 +956,6 @@ return function() { | ||
/** | ||
* qintervals.wrap(data) | ||
* | ||
* Create a new `qintervals` object wrapping an existing array of packed values. | ||
* | ||
* NOTE: If data is well-formed no copy will be created. | ||
*/ | ||
qintervals.wrap = wrap; | ||
/** | ||
* Get a reference to the internal packed data. | ||
* | ||
* NOTE: You shouldn't not change the data unless you are not gonna use the | ||
* `qintervals` object anymore. | ||
*/ | ||
// Get a reference to the internal packed data. | ||
// | ||
// NOTE: You shouldn't not change the data unless you are not gonna use the | ||
// `qintervals` object anymore. | ||
qintervals.prototype.getData = function() { | ||
@@ -988,5 +965,3 @@ return this.data; | ||
/** | ||
* Return a copy of `qintervals` data in a packed format. | ||
*/ | ||
// Return a copy of `qintervals` data in a packed format. | ||
qintervals.prototype.toPacked = function() { | ||
@@ -997,10 +972,8 @@ var data = this.data; | ||
/** | ||
* Convert a `qintervals` object into an array of arrays: | ||
* | ||
* For example an interval: | ||
* [1, 2, 3, 4] | ||
* would be converted to: | ||
* [[1, 2], [3, 4]] | ||
*/ | ||
// Convert a `qintervals` object into an array of arrays: | ||
// | ||
// For example an interval: | ||
// [1, 2, 3, 4] | ||
// would be converted to: | ||
// [[1, 2], [3, 4]] | ||
qintervals.prototype.toArrays = function() { | ||
@@ -1018,10 +991,8 @@ var output = []; | ||
/** | ||
* Convert a `qintervals` object into an array of objects: | ||
* | ||
* For example an interval: | ||
* [1, 2, 3, 4] | ||
* would be converted to: | ||
* [{ from: 1, to: 2}, { from: 3, to: 4 }] | ||
*/ | ||
// Convert a `qintervals` object into an array of objects: | ||
// | ||
// For example an interval: | ||
// [1, 2, 3, 4] | ||
// would be converted to: | ||
// [{ from: 1, to: 2}, { from: 3, to: 4 }] | ||
qintervals.prototype.toObjects = function(aKey, bKey) { | ||
@@ -1046,7 +1017,5 @@ if (!aKey) aKey = "from"; | ||
/** | ||
* qintervals.prototype.toString() | ||
* | ||
* Return interval as a string. | ||
*/ | ||
// \function `qintervals.prototype.toString()` | ||
// | ||
// Return interval as a string. | ||
qintervals.prototype.toString = function() { | ||
@@ -1056,8 +1025,6 @@ return this.data.toString(); | ||
/** | ||
* qintervals.equals(a, b) | ||
* qintervals.prototype.equals(other) | ||
* | ||
* Get whether two interval lists are equal. | ||
*/ | ||
// \function `qintervals.equals(a, b)` | ||
// \function `qintervals.prototype.equals(other)` | ||
// | ||
// Get whether two interval lists are equal. | ||
qintervals.equals = function(a, b) { | ||
@@ -1073,7 +1040,5 @@ return equals(dataFromArg(a), dataFromArg(b)); | ||
/** | ||
* qintervals.prototype.isEmpty() | ||
* | ||
* Get whether the list of intervals is empty. | ||
*/ | ||
// \function `qintervals.prototype.isEmpty()` | ||
// | ||
// Get whether the list of intervals is empty. | ||
qintervals.prototype.isEmpty = function() { | ||
@@ -1083,7 +1048,5 @@ return this.data.length === 0; | ||
/** | ||
* qintervals.prototype.getCount() | ||
* | ||
* Get count of intervals stored. | ||
*/ | ||
// \function `qintervals.prototype.getCount()` | ||
// | ||
// Get count of intervals stored. | ||
qintervals.prototype.getCount = function() { | ||
@@ -1093,5 +1056,3 @@ return this.data.length; | ||
/** | ||
* qintervals.prototype.clear() | ||
*/ | ||
// \function `qintervals.prototype.clear()` | ||
qintervals.prototype.clear = function() { | ||
@@ -1102,13 +1063,11 @@ this.data.length = 0; | ||
/** | ||
* qintervals.test(self, value) | ||
* qintervals.prototype.test(value) | ||
* | ||
* Test whether the list of intervals contains a scalar value or another list. | ||
* | ||
* The function can return the following values: | ||
* - `kTestNone` - No match. | ||
* - `kTestFull` - Full match. | ||
* - `kTestPart` - Partial match. | ||
*/ | ||
// \function `qintervals.test(self, value)` | ||
// \function `qintervals.prototype.test(value)` | ||
// | ||
// Test whether the list of intervals contains a scalar value or another list. | ||
// | ||
// The function can return the following values: | ||
// - `kTestNone` - No match. | ||
// - `kTestFull` - Full match. | ||
// - `kTestPart` - Partial match. | ||
qintervals.test = function(a, value) { | ||
@@ -1169,12 +1128,10 @@ if (typeof value === "number") { | ||
/** | ||
* qintervals.shift(a, value) | ||
* qintervals.prototype.shift(value) | ||
* | ||
* Shift a list of intervals `a` by a scalar `value`, returning a new `qintervals`. | ||
* | ||
* NOTE: If you store intervals as floating point numbers shifting can cause | ||
* the number of intervals to decrease if rounding caused one or more interval | ||
* to became continuous. | ||
*/ | ||
// \function `qintervals.shift(a, value)` | ||
// \function `qintervals.prototype.shift(value)` | ||
// | ||
// Shift a list of intervals `a` by a scalar `value`, returning a new `qintervals`. | ||
// | ||
// NOTE: If you store intervals as floating point numbers shifting can cause | ||
// the number of intervals to decrease if rounding caused one or more interval | ||
// to became continuous. | ||
qintervals.shift = function(a, value) { | ||
@@ -1221,65 +1178,65 @@ return new qintervals(shiftOp(dataFromArg(a), value)); | ||
/** | ||
* qintervals.union(...) | ||
* qintervals.or(...) | ||
* | ||
* Union two or more lists of intervals, returninig a new `qintervals`. | ||
* | ||
* qintervals.prototype.or(...) | ||
* qintervals.prototype.union(...) | ||
* | ||
* Union with one or more interval lists in-place. | ||
*/ | ||
qintervals.prototype.or = memberOp(orOp, mergeOp); | ||
// \function `qintervals.union(...)` | ||
// \function `qintervals.or(...)` | ||
// | ||
// Union two or more lists of intervals, returninig a new `qintervals`. | ||
qintervals.union = | ||
qintervals.or = | ||
staticOp(orOp); | ||
qintervals.union = qintervals.or = staticOp(orOp); | ||
qintervals.prototype.union = qintervals.prototype.or; | ||
// \function `qintervals.prototype.union(...)` | ||
// \function `qintervals.prototype.or(...)` | ||
// | ||
// Union with one or more interval lists in-place. | ||
qintervals.prototype.union = | ||
qintervals.prototype.or = | ||
memberOp(orOp, mergeOp); | ||
/** | ||
* qintervals.intersect(...) | ||
* qintervals.and(...) | ||
* | ||
* Intersect two or more lists of intervals, returninig a new `qintervals`. | ||
* | ||
* qintervals.prototype.and(...) | ||
* qintervals.prototype.intersect(...) | ||
* | ||
* Intersect with one or more interval lists in-place. | ||
*/ | ||
qintervals.prototype.and = memberOp(andOp, clearOp); | ||
// \function `qintervals.intersect(...)` | ||
// \function `qintervals.and(...)` | ||
// | ||
// Intersect two or more lists of intervals, returninig a new `qintervals`. | ||
qintervals.intersect = | ||
qintervals.and = | ||
staticOp(andOp); | ||
qintervals.intersect = qintervals.and = staticOp(andOp); | ||
qintervals.prototype.intersect = qintervals.prototype.and; | ||
// \function `qintervals.prototype.intersect(...)` | ||
// \function `qintervals.prototype.and(...)` | ||
// | ||
// Intersect with one or more interval lists in-place. | ||
qintervals.prototype.intersect = | ||
qintervals.prototype.and = | ||
memberOp(andOp, clearOp); | ||
/** | ||
* qintervals.xor(...) | ||
* | ||
* Xor two or more lists of intervals, returninig a new `qintervals`. | ||
* | ||
* qintervals.prototype.xor(...) | ||
* | ||
* Xor with one or more interval lists in-place. | ||
*/ | ||
qintervals.prototype.xor = memberOp(xorOp, mergeOp); | ||
// \function `qintervals.xor(...)` | ||
// | ||
// Xor two or more lists of intervals, returninig a new `qintervals`. | ||
qintervals.xor = | ||
staticOp(xorOp); | ||
qintervals.xor = staticOp(xorOp); | ||
// \function `qintervals.prototype.xor(...)` | ||
// | ||
// Xor with one or more interval lists in-place. | ||
qintervals.prototype.xor = | ||
memberOp(xorOp, mergeOp); | ||
/** | ||
* qintervals.subtract(...) | ||
* qintervals.sub(...) | ||
* | ||
* Subtract two or more lists of intervals, returninig a new `qintervals`. | ||
* | ||
* qintervals.prototype.subtract(...) | ||
* qintervals.prototype.sub(...) | ||
* | ||
* Subtract with one or more interval lists in-place. | ||
*/ | ||
qintervals.prototype.sub = memberOp(subOp, noOp); | ||
// \function `qintervals.subtract(...)` | ||
// \function `qintervals.sub(...)` | ||
// | ||
// Subtract two or more lists of intervals, returninig a new `qintervals`. | ||
qintervals.subtract = qintervals.sub = staticOp(subOp); | ||
qintervals.prototype.subtract = qintervals.prototype.sub; | ||
qintervals.subtract = | ||
qintervals.sub = | ||
staticOp(subOp); | ||
// \function `qintervals.prototype.subtract(...)` | ||
// \function `qintervals.prototype.sub(...)` | ||
// | ||
// Subtract with one or more interval lists in-place. | ||
qintervals.prototype.subtract = | ||
qintervals.prototype.sub = | ||
memberOp(subOp, noOp); | ||
$export[$as] = qintervals; | ||
}).apply(this, typeof module === "object" ? [module, "exports"] : [this, "qintervals"]); |
@@ -57,3 +57,3 @@ QIntervals | ||
To wrap an existing data into the `qintervals` object, consider using `qintervals.wrap()`: | ||
To wrap an existing data into the `qintervals` object, consider using `qintervals.fromData()`: | ||
@@ -85,3 +85,3 @@ ```JS | ||
* AND - Use `qintervals.and` or `qintervals.intersect`. | ||
* OR - Use `qintervals.or` or `qintervals.union`. | ||
* OR - Use `qintervals.or` or `qintervals.union`. | ||
* XOR - Use `qintervals.xor`. | ||
@@ -88,0 +88,0 @@ * SUB - Use `qintervals.sub` or `qintervals.subtract`. |
Sorry, the diff of this file is not supported yet
40847
1146