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"]