Number Ranges
Data structure for working with sets of numbers and serializing as range strings.
Examples
import NumberRanges from '@scotttrinh/number-ranges';
// Constructor
// With Array
var myRange = new NumberRanges([0, 1, 2, 3, 5, 6]);
// With { start, end } object
var myExplicitRange = new NumberRanges({ start: 0, end: 3 });
// With NumberRanges
var myNumberRangesRange = new NumberRanges(myExplicitRange);
// String/JSON representation
console.log(myRange); // 0-3,5-6
console.log(myRange.toString()); // '0-3,5-6'
console.log(JSON.stringify({ range: myRange })); // {"range":"0-3,5-6"}
// Add items to the set
myRange.add([4]);
myRange.add([4]);
myRange.add([4]);
myRange.add(new Set([4])); // Works for TypedArray and ES2015 Set
console.log(myRange); // 0-6
var sixToTwelve = new NumberRanges({ start: 6, end: 12 });
myRange.union(sixToTwelve);
console.log(myRange); // 0-12
// Remove items from the set
myRange.remove([4, 1, 6]);
console.log(myRange); // 0-0,2-3,5-5
// Check for set membership
console.log(myRange.contains(2)); // true
console.log(myRange.contains(4)); // false
// Alternate Serializer
var alternateSerializer = function alternateSerializer(ranges) {
return ranges
.map(function (range) {
return '' + range[0] + ':'
})
.join('###');
}
var mySpecialRange = new NumberRanges([0, 1, 2, 3, 5, 6], { serializer: alternateSerializer });
console.log(mySpecialRange.toString()); // '0:3###5:6'
// Convert back to Array of (sorted) numbers
console.log(myRange.toArray()); // [0, 1, 2, 3, 5, 6]
// Find min/max
myRange.min(); // 0
myRange.max(); // 6
Constructor
NumberRanges: (Iterable<number> | NumberRanges | { start: number, end: number }) => void
-
input: Iterable<number> | NumberRanges | { start: number, end: number }
Numbers to add to the new NumberRanges object -
config
-
config.serializer: (ranges: Array<number, number>) => string
A function that receives an array of[start, end]
pairs and should return a string. Is used fortoString()
andtoJSON()
.
-
Constructor function that takes an Iterable<number>
, existing
NumberRanges
object, or { start: number, end: number }
object literal and
returns a NumberRanges
object representing the range of numbers passed. Has an
optional config
object that you can pass a serializer object. See toString()
and toJSON()
.
const missingBytes = new NumberRanges([0, 1, 2, 3, 4, 5]); // 0-5
const selectedProducts = new NumberRanges(new Set([0, 1, 1, 1, 2, 3, 3, 3])); // 0-3
const favoriteNumbers = new NumberRanges({ start: 0, end: 42 }); // 0-42
const rangesInception = new NumberRanges(new NumberRanges([42])); // 42
Properties
NumberRanges.ranges: Array<number, number>
If you would like to interact with the ranges directly, the raw
Array<number, number>
is at this property.
missingBytes.ranges; // [[0, 5]]
Methods
NumberRanges.add: (Iterable<number>) => NumberRanges
-
numbersToAdd: Iterable<number>
Numbers to add to this NumberRanges object - Returns:
NumberRanges
Adds the passed numbers to the NumberRanges set.
missingBytes.add([0, 6, 10]); // 0-6,10
NumberRanges.remove: (Iterable<number>) => NumberRanges
Removes the passed numbers from the NumberRanges set.
-
numbersToRemove: Iterable<number>
Numbers to remove from this NumberRanges object - Returns:
NumberRanges
missingBytes.remove([0, 6, 10]); // 0-5
NumberRanges.union: (NumberRanges) => NumberRanges
Set union
-
newRanges: NumberRanges
NumberRanges
to unite with thisNumberRanges
object - Returns:
NumberRanges
new NumberRanges([0, 2, 4]).union(new NumberRanges({ start: 0, end: 10 })); // 0-10
NumberRanges.difference: (NumberRanges) => NumberRanges
Set difference
-
newRanges: NumberRanges
NumberRanges
to subtract from thisNumberRanges
object - Returns:
NumberRanges
new NumberRanges([0, 1, 2, 5, 6, 7]).difference(new NumberRanges([0, 1, 5])); // 2,6-7
NumberRanges.contains: (number) => boolean
Search for existance of number in NumberRanges
.
-
needle: number
Number to search for in range. - Returns:
boolean
new NumberRanges([0,3,5]).contains(3); // true
NumberRanges.size: () => number
Returns the number of elements in the NumberRanges
- Returns:
number
new NumberRanges({ start: 0, end: 99 }).size(); // 100
NumberRanges.min: () => number | null
Returns the smallest number in the range or null
if the range is empty.
- Returns:
number | null
new NumberRanges([10, 32, 238, 1, 43]).min(); // 1
new NumberRanges([]).min(); // null
NumberRanges.max: () => number | null
Returns the largest number in the range or null
if the range is empty.
- Returns:
number | null
new NumberRanges([0, 3, 2, 8, 10, 99, 1]).max(); // 99
new NumberRanges([]).max(); // null
NumberRanges.toString: () => string
NumberRanges.toJSON: () => string
By default, returns a string like 0-0,10-20,500-600,723-723
, but can be replaced by
passing a custom serializer function when constructed.
The custom serializer will be passed an Array<number, number>
where the
number
s represent the start and end of each contiguous range. Note that these
numbers might be the same for ranges that are a single number.
- Returns:
string
new NumberRanges([0, 2, 3]).toString(); // '0-0,2-3'
new NumberRanges(
[-1, 0, 2, 3, 5],
{
serializer: (ranges) => ranges
.map(range => `${range[0]}:${range[1]}`)
.join('###')
}
).toString(); // '-1:0###2:3##5:5'
NumberRanges.toArray: () => Array<number>
Convert to an Array containing all numbers in the range. The ranges sorted
internally, so NumberRanges
is not isomorphic to the origin Iterable
, but
will contain all elements.
- Returns:
Array<number>
new NumberRanges([3, 2, 1]).toArray(); // [1, 2, 3]
new NumberRanges({ start: 2, end: 10 }).toArray(); // [2, 3, 4, 5, 6, 7, 8, 9, 10]
NumberRanges.findContaining: (needles: Array<number>) => NumberRanges | null
Return a new NumberRanges
object that is the matching range that contains all of
the needles
numbers.
-
needles: Array<number>
Numbers to match the range - Returns: new
NumberRanges
const ranges = new NumberRanges([0, 1, 2, 3, 5, 6]);
ranges.findContaining([0]); // 0-3
ranges.findContaining([0, 2]); // 0-3
ranges.findContaining([0, 5]); // null
ranges.findContaining([4, 9]); // null