struct Range(B, E)

Overview

ARange 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

SeeRange literals in the language reference.

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

Ranges typically involve integers, but can be created using arbitrary objects as long as they definesucc (orpred 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 usingXs 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

Included Modules

Defined in:

range.cr
range/bsearch.cr

Constructors

Instance Method Summary

Instance methods inherited from module Iterable(B)

chunk(reuse = false, &block : T -> U) forall U chunk, chunk_while(reuse : Bool | Array(T) = false, &block : T, T -> B) forall B chunk_while, cycle(n)
cycle
cycle
, each each, each_cons(count : Int, reuse = false) each_cons, each_cons_pair each_cons_pair, each_slice(count : Int, reuse = false) each_slice, each_step(n : Int)
each_step(n : Int, *, offset : Int)
each_step
, each_with_index(offset = 0) each_with_index, each_with_object(obj) each_with_object, slice_after(reuse : Bool | Array(T) = false, &block : T -> B) forall B
slice_after(pattern, reuse : Bool | Array(T) = false)
slice_after
, slice_before(reuse : Bool | Array(T) = false, &block : T -> B) forall B
slice_before(pattern, reuse : Bool | Array(T) = false)
slice_before
, slice_when(reuse : Bool | Array(T) = false, &block : T, T -> B) forall B slice_when

Instance methods inherited from module Enumerable(B)

accumulate(initial : U) : Array(U) forall U
accumulate : Array(T)
accumulate(initial : U, &block : U, T -> U) : Array(U) forall U
accumulate(&block : T, T -> T) : Array(T)
accumulate
, all?(& : T -> ) : Bool
all?(pattern) : Bool
all? : Bool
all?
, any?(& : T -> ) : Bool
any?(pattern) : Bool
any? : Bool
any?
, chunks(&block : T -> U) forall U chunks, compact_map(& : T -> _) compact_map, count(& : T -> ) : Int32
count(item) : Int32
count
, cycle(n, & : T -> ) : Nil
cycle(& : T -> ) : Nil
cycle
, each(& : T -> ) each, each_cons(count : Int, reuse = false, &) each_cons, each_cons_pair(& : T, T -> ) : Nil each_cons_pair, each_slice(count : Int, reuse = false, &) each_slice, each_step(n : Int, *, offset : Int = 0, & : T -> ) : Nil each_step, each_with_index(offset = 0, &) each_with_index, each_with_object(obj : U, & : T, U -> ) : U forall U each_with_object, empty? : Bool empty?, find(if_none = nil, & : T -> ) find, find!(& : T -> ) : T find!, find_value(if_none = nil, & : T -> ) find_value, first(&)
first(count : Int) : Array(T)
first : T
first
, first? : T | Nil first?, flat_map(& : T -> _) flat_map, group_by(& : T -> U) forall U group_by, in_groups_of(size : Int, filled_up_with : U = nil) forall U
in_groups_of(size : Int, filled_up_with : U = nil, reuse = false, &) forall U
in_groups_of
, in_slices_of(size : Int) : Array(Array(T)) in_slices_of, includes?(obj) : Bool includes?, index(& : T -> ) : Int32 | Nil
index(obj) : Int32 | Nil
index
, index!(& : T -> ) : Int32
index!(obj) : Int32
index!
, index_by(& : T -> U) : Hash(U, T) forall U index_by, join(io : IO, separator = "") : Nil
join(separator, io : IO) : Nil
join(separator = "") : String
join(io : IO, separator = "", & : T, IO -> )
join(separator, io : IO, &)
join(separator = "", & : T -> )
join
, map(& : T -> U) : Array(U) forall U map, map_with_index(offset = 0, & : T, Int32 -> U) : Array(U) forall U map_with_index, max(count : Int) : Array(T)
max : T
max
, max? : T | Nil max?, max_by(& : T -> U) : T forall U max_by, max_by?(& : T -> U) : T | Nil forall U max_by?, max_of(& : T -> U) : U forall U max_of, max_of?(& : T -> U) : U | Nil forall U max_of?, min(count : Int) : Array(T)
min : T
min
, min? : T | Nil min?, min_by(& : T -> U) : T forall U min_by, min_by?(& : T -> U) : T | Nil forall U min_by?, min_of(& : T -> U) : U forall U min_of, min_of?(& : T -> U) : U | Nil forall U min_of?, minmax : Tuple(T, T) minmax, minmax? : Tuple(T | Nil, T | Nil) minmax?, minmax_by(& : T -> U) : Tuple(T, T) forall U minmax_by, minmax_by?(& : T -> U) : Tuple(T, T) | Tuple(Nil, Nil) forall U minmax_by?, minmax_of(& : T -> U) : Tuple(U, U) forall U minmax_of, minmax_of?(& : T -> U) : Tuple(U, U) | Tuple(Nil, Nil) forall U minmax_of?, none?(& : T -> ) : Bool
none?(pattern) : Bool
none? : Bool
none?
, one?(& : T -> ) : Bool
one?(pattern) : Bool
one? : Bool
one?
, partition(& : T -> ) : Tuple(Array(T), Array(T))
partition(type : U.class) forall U
partition
, present? : Bool present?, product(initial : Number)
product
product(initial : Number, & : T -> )
product(& : T -> _)
product
, reduce(memo, &)
reduce(&)
reduce
, reduce?(&) reduce?, reject(& : T -> )
reject(type : U.class) forall U
reject(pattern) : Array(T)
reject
, sample(n : Int, random : Random | Nil = nil) : Array(T)
sample(random : Random | Nil = nil) : T
sample
, select(& : T -> )
select(type : U.class) : Array(U) forall U
select(pattern) : Array(T)
select
, size : Int32 size, skip(count : Int) skip, skip_while(& : T -> ) : Array(T) skip_while, sum(initial)
sum
sum(initial, & : T -> )
sum(& : T -> )
sum
, take_while(& : T -> ) : Array(T) take_while, tally(hash)
tally : Hash(T, Int32)
tally
, tally_by(hash, &)
tally_by(&block : T -> U) : Hash(U, Int32) forall U
tally_by
, to_a : Array(T)
to_a(& : T -> U) : Array(U) forall U
to_a
, to_h
to_h(& : T -> Tuple(K, V)) forall K, V
to_h
, to_set : Set(T)
to_set(&block : T -> U) : Set(U) forall U
to_set
, zip(*others : Indexable | Iterable | Iterator, &)
zip(*others : Indexable | Iterable | Iterator)
zip
, zip?(*others : Indexable | Iterable | Iterator, &)
zip?(*others : Indexable | Iterable | Iterator)
zip?

Class methods inherited from module Enumerable(B)

element_type(x) element_type

Instance methods inherited from struct Struct

==(other : YAML::Any)
==(other) : Bool
==
, hash(hasher) hash, inspect(io : IO) : Nil inspect, pretty_print(pp) : Nil pretty_print, to_s(io : IO) : Nil to_s

Class methods inherited from struct Struct

pre_initialize(address : Pointer) : Nil pre_initialize

Instance methods inherited from struct Value

==(other : Log::Metadata::Value)
==(other : JSON::Any)
==(other : YAML::Any)
==(other)
==
, dup dup

Instance methods inherited from class Object

! : Bool !, !=(other) !=, !~(other) !~, ==(other) ==, ===(other : JSON::Any)
===(other : YAML::Any)
===(other)
===
, =~(other) =~, as(type : Class) as, as?(type : Class) as?, class class, dup dup, hash(hasher)
hash
hash
, in?(collection : Object) : Bool
in?(*values : Object) : Bool
in?
, inspect(io : IO) : Nil
inspect : String
inspect
, is_a?(type : Class) : Bool is_a?, itself itself, nil? : Bool nil?, not_nil!(message)
not_nil!
not_nil!
, pretty_inspect(width = 79, newline = "\n", indent = 0) : String pretty_inspect, pretty_print(pp : PrettyPrint) : Nil pretty_print, responds_to?(name : Symbol) : Bool responds_to?, tap(&) tap, to_json(io : IO) : Nil
to_json : String
to_json
, to_pretty_json(indent : String = " ") : String
to_pretty_json(io : IO, indent : String = " ") : Nil
to_pretty_json
, to_s(io : IO) : Nil
to_s : String
to_s
, to_yaml(io : IO) : Nil
to_yaml : String
to_yaml
, try(&) try, unsafe_as(type : T.class) forall T unsafe_as

Class methods inherited from class Object

from_json(string_or_io : String | IO, root : String)
from_json(string_or_io : String | IO)
from_json
, from_yaml(string_or_io : String | IO) from_yaml

Macros inherited from class Object

class_getter(*names, &block) class_getter, class_getter!(*names) class_getter!, class_getter?(*names, &block) class_getter?, class_property(*names, &block) class_property, class_property!(*names) class_property!, class_property?(*names, &block) class_property?, class_setter(*names) class_setter, def_clone def_clone, def_equals(*fields) def_equals, def_equals_and_hash(*fields) def_equals_and_hash, def_hash(*fields) def_hash, delegate(*methods, to object) delegate, forward_missing_to(delegate) forward_missing_to, getter(*names, &block) getter, getter!(*names) getter!, getter?(*names, &block) getter?, property(*names, &block) property, property!(*names) property!, property?(*names, &block) property?, setter(*names) setter

Constructor Detail

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

Constructs aRange using the given beginning and end.

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

Instance Method Detail

def ==(other : Range) #

def ===(value) #

Same as#includes?, useful for thecase 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 : B #

Returns the object that defines the beginning of this range.

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

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

By using binary search, returns the first element for which the passed block returns a truthy value.

If the block returns a falsey value, the element to be found lies behind. If the block returns a truthy value, the element to be found is itself or lies in front.

Returnsnil if the block didn't return a truthy value for any element.

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

def clone #

Returns a newRange with#begin and#end cloned.


def covers?(value) #

Same as#includes?.


def cycle #

Returns anIterator that cycles over the values of this range.

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

def each(&) : Nil #

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 each #

Returns anIterator over the elements of this range.

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

def end : E #

Returns the object that defines the end of the range.

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

def excludes_end? : Bool #

Returnstrue if this range excludes theend element.

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

def exclusive? : Bool #

Returnstrue if the range is exclusive. Returnsfalse otherwise (default).


def includes?(value) : Bool #

Returnstrue if this range includes the givenvalue.

(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 inspect(io : IO) : Nil #
Description copied from struct Struct

Appends this struct's name and instance variables names and values to the given IO.

struct Point
  def initialize(@x : Int32, @y : Int32)
  end
end

p1 = Point.new 1, 2
p1.to_s    # "Point(@x=1, @y=2)"
p1.inspect # "Point(@x=1, @y=2)"

def map(&block : B -> U) forall U #
Description copied from module Enumerable(B)

Returns anArray with the results of running the block against each element of the collection.

[1, 2, 3].map { |i| i * 10 } # => [10, 20, 30]

def reverse_each(&) : Nil #

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_each #

Returns a reverseIterator over the elements of this range.

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

def sample(random : Random | Nil = nil) #

Optimized version ofEnumerable#sample that runs in O(1) time whenself is anInt orFloat range. In these cases, this range is considered to be a distribution of numeric values rather than a collection of elements, and the method simply callsrandom.rand(self).

RaisesArgumentError ifself is an open range.


def sample(n : Int, random : Random | Nil = nil) #

Returns anArray ofn random elements fromself. All elements have equal probability of being drawn. Sampling is done without replacement; if n is larger than the size of this collection, the returnedArray has the same size asself.

RaisesArgumentError ifn is negative.

[1, 2, 3, 4, 5].sample(2) # => [3, 5]
{1, 2, 3, 4, 5}.sample(2) # => [3, 4]

Uses therandom instance when provided if the randomness needs to be controlled or to follow some traits. For example the following calls use a custom seed or a secure random source:

{1, 2, 3, 4, 5}.sample(2, Random.new(1))  # => [1, 5]
{1, 2, 3, 4, 5}.sample(2, Random::Secure) # => [2, 5]

Ifself is not empty andn is equal to 1, calls#sample(random) exactly once. Thus,random will be left in a different state compared to the implementation inEnumerable.


def size : Int32 #

Returns the number of values in this range.

If both the beginning and the end of this range areInts, runs in constant time instead of linear.

(3..8).size  # => 6
(3...8).size # => 5

RaisesOverflowError if the difference is bigger thanInt32. RaisesArgumentError if either#begin or#end arenil.


def step(by = 1, &) : Nil #

Iterates from#begin to#end incrementing by the amount ofstep on each iteration.

ary = [] of Int32
(1..4).step(by: 2) do |x|
  ary << x
end
ary                      # => [1, 3]
(1..4).step(by: 2).to_a  # => [1, 3]
(1..4).step(by: 1).to_a  # => [1, 2, 3, 4]
(1...4).step(by: 1).to_a # => [1, 2, 3]

IfB is aSteppable, implementation is delegated toSteppable#step. Otherwise#succ method is expected to be defined on#begin and its successors and iteration is based on calling#succ sequentially (step times per iteration).

RaisesArgumentError if#begin isnil.


def step(by = 1) : Iterator #

Iterates from#begin to#end incrementing by the amount ofstep on each iteration.

ary = [] of Int32
(1..4).step(by: 2) do |x|
  ary << x
end
ary                      # => [1, 3]
(1..4).step(by: 2).to_a  # => [1, 3]
(1..4).step(by: 1).to_a  # => [1, 2, 3, 4]
(1...4).step(by: 1).to_a # => [1, 2, 3]

IfB is aSteppable, implementation is delegated toSteppable#step. Otherwise#succ method is expected to be defined on#begin and its successors and iteration is based on calling#succ sequentially (step times per iteration).

RaisesArgumentError if#begin isnil.


def sum(initial) #

Optimized version ofEnumerable#sum that runs in O(1) time whenself is anInt range.


def to_s(io : IO) : Nil #
Description copied from struct Struct

Same as#inspect(io).