Range
The Range class is used to represent intervals – sequences with a start and
end value. It is directly based on Ruby’s
Range class.
// In the browser
JS.require('JS.Range', function(Range) { ... });
// In CommonJS
var Range = require('jsclass/src/range').Range;
A Range may be constructed using integers, strings, or any type of object
that responds to the succ() method. Ranges are a lightweight way to
represent sequences of objects, and as collections they respond to all the
Enumerable methods.
A range is constructed using a start and end value, and an optional flag that indicates whether the end value is included when iterating.
new Range(1,5) // -> 1,2,3,4,5
new Range(4,8,true) // -> 4,5,6,7
new Range('a','d') // -> 'a','b','c','d'
new Range('B','G',true) // -> 'B','C','D','E','F'
The Range object only stores the start and endpoints, not the intermediate
values: these are generated using succ() when iterating. For example, here’s
a quick class that implements enough of an API to be used as a Range
delimiter. We need succ() to return the next object in the sequence, and
compareTo() to allow a Range to determine whether a
given object is within the range:
var NumberWrapper = new Class({
initialize: function(value) {
this._value = value;
},
compareTo: function(object) {
var a = this._value, b = object._value;
return a < b ? -1 : (a > b ? 1 : 0);
},
succ: function() {
return new this.klass(this._value + 1);
},
inspect: function() {
return '#<NumberWrapper:' + this._value + '>';
}
});
We can use this class in a Range and iterating will generate the
intermediate objects:
var nums = new Range(new NumberWrapper(16),
new NumberWrapper(24),
true);
nums.forEach(function(number) {
console.log(number.inspect());
});
// -> #<NumberWrapper:16>
// #<NumberWrapper:17>
// #<NumberWrapper:18>
// #<NumberWrapper:19>
// #<NumberWrapper:20>
// #<NumberWrapper:21>
// #<NumberWrapper:22>
// #<NumberWrapper:23>
The full Range object API is listed below. Ranges also respond to all the
Enumerable methods based on the forEach() method.
begin()
Returns the start value of the Range.
forEach(block, context)
Calls block with each item in the Range in turn. context is optional and
specifies the binding of this within the block function.
// Calls the function with
// arguments 1,2,3,4
new Range(1,4).forEach(function(number) {
// ...
});
end()
Returns the end value of the Range.
equals(other)
Returns true iff other is a Range with the same start and end values and
the same value for excludesEnd(). Note that the ranges new Range(1,4)
and new Range(1,5,true) are not equal.
excludesEnd()
Returns true iff the Range excludes its end value during iteration.
first()
Returns the start value of the Range.
includes(item)
Returns true iff item is contained in the Range, that is if it is between
the start and end values of the range.
new Range(1,4).includes(3) // -> true new Range(2,6,true).includes(6) // -> false
Note that an object may be considered to be included in a range even though it
does not appear during iteration and may even lie outside the iteration range.
For example the following expression is true as 8.5 is less than 9:
new Range(6,9,true).includes(8.5) // -> true
Aliased as covers(), member() and match(), so a Range may be used as
the argument to Enumerable#grep.
last()
Returns the end value of the Range.
step(n, block, context)
Iterates over every nth item in the Range, calling block with each. Returns
an Enumerator if called with no block.
new Range('G','V').step(5).entries()
// -> ["G", "L", "Q", "V"]