/Crystal

# struct Range(B, E)

## Overview

A `Range` represents an interval: a set of values with a beginning and an end.

Ranges may be constructed using the usual `.new` method or with literals:

```x..y  # an inclusive range, in mathematics: [x, y]
x...y # an exclusive range, in mathematics: [x, y)
(x..) # an endless range, in mathematics: >= x
..y   # a beginless inclusive range, in mathematics: <= y
...y  # a beginless exclusive range, in mathematics: < y```

An easy way to remember which one is inclusive and which one is exclusive it to think of the extra dot as if it pushes y further away, thus leaving it outside of the range.

Ranges typically involve integers, but can be created using arbitrary objects as long as they define `succ` (or `pred` for `#reverse_each`), to get the next element in the range, and `<` and `==`, to know when the range reached the end:

```# Represents a string of 'x's.
struct Xs
include Comparable(Xs)

getter size

def initialize(@size : Int32)
end

def succ
Xs.new(@size + 1)
end

def <=>(other)
@size <=> other.size
end

def inspect(io)
@size.times { io << 'x' }
end

def to_s(io)
io << @size << ' '
inspect(io)
end
end```

An example of using `Xs` to construct a range:

```r = Xs.new(3)..Xs.new(6)
r.to_s                 # => "xxx..xxxxxx"
r.to_a                 # => [Xs.new(3), Xs.new(4), Xs.new(5), Xs.new(6)]
r.includes?(Xs.new(5)) # => true```

range.cr
range/bsearch.cr

## Instance Method Summary

• #===(value)

Same as `#includes?`, useful for the `case` expression.

• #begin : B

Returns the object that defines the beginning of this range.

• #bsearch(&block : B | E -> Bool)

By using binary search, returns the first value for which the passed block returns `true`.

• #clone

Returns a new `Range` with `#begin` and `#end` cloned.

• #covers?(value)

Same as `#includes?`.

• #cycle

Returns an `Iterator` that cycles over the values of this range.

• #each(&) : Nil

Iterates over the elements of this range, passing each in turn to the block.

• #each

Returns an `Iterator` over the elements of this range.

• #end : E

Returns the object that defines the end of the range.

• #excludes_end?

Returns `true` if this range excludes the end element.

• #exclusive? : Bool

Returns `true` if the range is exclusive.

• #includes?(value)

Returns `true` if this range includes the given value.

• #reverse_each(&) : Nil

Iterates over the elements of this range in reverse order, passing each in turn to the block.

• #reverse_each

Returns a reverse `Iterator` over the elements of this range.

• #step(by = 1)

Returns an `Iterator` that returns each nth element in this range.

• #step(by = 1, &)

Iterates over this range, passing each nth element to the block.

• #sum(initial)

If `self` is a `Int` range, it provides O(1) implementation, otherwise it is same as `Enumerable#sum`.

## Constructor Detail

### def self.new(begin __arg0 : B, end __arg1 : E, exclusive : Bool = false)Source

Constructs a `Range` using the given beginning and end.

```Range.new(1, 10)                  # => 1..10
Range.new(1, 10, exclusive: true) # => 1...10```

## Instance Method Detail

### def ===(value)Source

Same as `#includes?`, useful for the `case` expression.

```case 79
when 1..50   then puts "low"
when 51..75  then puts "medium"
when 76..100 then puts "high"
end```

Produces:

`high`

See also: `Object#===`.

### def begin : BSource

Returns the object that defines the beginning of this range.

```(1..10).begin  # => 1
(1...10).begin # => 1```

### def bsearch(&block : B | E -> Bool)Source

By using binary search, returns the first value for which the passed block returns `true`.

If the block returns `false`, the finding value exists behind. If the block returns `true`, the finding value is itself or exists infront.

```(0..10).bsearch { |x| x >= 5 }                       # => 5
(0..Float64::INFINITY).bsearch { |x| x ** 4 >= 256 } # => 4```

Returns `nil` if the block didn't return `true` for any value.

### def cloneSource

Returns a new `Range` with `#begin` and `#end` cloned.

### def covers?(value)Source

Same as `#includes?`.

### def cycleSource

Returns an `Iterator` that cycles over the values of this range.

`(1..3).cycle.first(5).to_a # => [1, 2, 3, 1, 2]`

### def each(&) : NilSource

Iterates over the elements of this range, passing each in turn to the block.

```(10..15).each { |n| print n, ' ' }
# prints: 10 11 12 13 14 15```

### def eachSource

Returns an `Iterator` over the elements of this range.

`(1..3).each.skip(1).to_a # => [2, 3]`

### def end : ESource

Returns the object that defines the end of the range.

```(1..10).end  # => 10
(1...10).end # => 10```

### def excludes_end?Source

Returns `true` if this range excludes the end element.

```(1..10).excludes_end?  # => false
(1...10).excludes_end? # => true```

### def exclusive? : BoolSource

Returns `true` if the range is exclusive. Returns `false` otherwise (default).

### def includes?(value)Source

Returns `true` if this range includes the given value.

```(1..10).includes?(4)  # => true
(1..10).includes?(10) # => true
(1..10).includes?(11) # => false

(1...10).includes?(9)  # => true
(1...10).includes?(10) # => false```

### def reverse_each(&) : NilSource

Iterates over the elements of this range in reverse order, passing each in turn to the block.

```(10...15).reverse_each { |n| print n, ' ' }
# prints: 14 13 12 11 10```

### def reverse_eachSource

Returns a reverse `Iterator` over the elements of this range.

`(1..3).reverse_each.skip(1).to_a # => [2, 1]`

### def step(by = 1)Source

Returns an `Iterator` that returns each nth element in this range.

`(1..10).step(3).skip(1).to_a # => [4, 7, 10]`

### def step(by = 1, &)Source

Iterates over this range, passing each nth element to the block.

```range = Xs.new(1)..Xs.new(10)
range.step(2) { |x| puts x }
puts
range.step(3) { |x| puts x }```

Produces:

```1 x
3 xxx
5 xxxxx
7 xxxxxxx
9 xxxxxxxxx

1 x
4 xxxx
7 xxxxxxx
10 xxxxxxxxxx```

See `Range`'s overview for the definition of `Xs`.

### def sum(initial)Source

If `self` is a `Int` range, it provides O(1) implementation, otherwise it is same as `Enumerable#sum`.