Skip to content

module Indexable(T)

A container that allows accessing elements via a numeric index.

Indexing starts at 0. A negative index is assumed to be relative to the end of the container: -1 indicates the last element, -2 is the next to last element, and so on.

Types including this module are typically Array-like types.

Included modules

Enumerable Iterable

Direct including types

Array(T) BitArray Deque(T) LLVM::ParameterCollection Slice(T) StaticArray(T, N) Tuple(*T)

Methods

#[](index : Int)

Returns the element at the given index.

Negative indices can be used to start counting from the end of the array. Raises IndexError if trying to access an element outside the array's range.

ary = ['a', 'b', 'c']
ary[0]  # => 'a'
ary[2]  # => 'c'
ary[-1] # => 'c'
ary[-2] # => 'b'

ary[3]  # raises IndexError
ary[-4] # raises IndexError
View source

#[]?(index : Int)

Returns the element at the given index.

Negative indices can be used to start counting from the end of the array. Returns nil if trying to access an element outside the array's range.

ary = ['a', 'b', 'c']
ary[0]?  # => 'a'
ary[2]?  # => 'c'
ary[-1]? # => 'c'
ary[-2]? # => 'b'

ary[3]?  # nil
ary[-4]? # nil
View source

#bsearch(&block : T -> Bool)

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

If the block returns false, the finding element exists behind. If the block returns true, the finding element is itself or exists in front.

Binary search needs sorted array, so self has to be sorted.

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

[2, 5, 7, 10].bsearch { |x| x >= 4 } # => 5
[2, 5, 7, 10].bsearch { |x| x > 10 } # => nil
View source

#bsearch_index(&block : T, Int32 -> Bool)

By using binary search, returns the index of the first element for which the passed block returns true.

If the block returns false, the finding element exists behind. If the block returns true, the finding element is itself or exists in front.

Binary search needs sorted array, so self has to be sorted.

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

[2, 5, 7, 10].bsearch_index { |x, i| x >= 4 } # => 1
[2, 5, 7, 10].bsearch_index { |x, i| x > 10 } # => nil
View source

#combinations(size : Int = self.size)

View source

#dig(index : Int, *subindexes)

Traverses the depth of a structure and returns the value, otherwise raises IndexError.

ary = [{1, 2, 3, {4, 5, 6}}]
ary.dig(0, 3, 2) # => 6
ary.dig(0, 3, 3) # raises IndexError
View source

#dig?(index : Int, *subindexes)

Traverses the depth of a structure and returns the value. Returns nil if not found.

ary = [{1, 2, 3, {4, 5, 6}}]
ary.dig?(0, 3, 2) # => 6
ary.dig?(0, 3, 3) # => nil
View source

#each(*, within range : Range

Calls the given block once for all elements at indices within the given range, passing each element as a parameter.

Raises IndexError if the starting index is out of range.

array = ["a", "b", "c", "d", "e"]
array.each(within: 1..3) { |x| print x, " -- " }

produces:

b -- c -- d --
View source

#each

Returns an Iterator for the elements of self.

a = ["a", "b", "c"]
iter = a.each
iter.next # => "a"
iter.next # => "b"

The returned iterator keeps a reference to self: if the array changes, the returned values of the iterator change as well.

View source

#each

Calls the given block once for each element in self, passing that element as a parameter.

a = ["a", "b", "c"]
a.each { |x| print x, " -- " }

produces:

a -- b -- c --
View source

#each(*, start : Int, count : Int

Calls the given block once for count number of elements in self starting from index start, passing each element as a parameter.

Negative indices count backward from the end of the array. (-1 is the last element).

Raises IndexError if the starting index is out of range. Raises ArgumentError if count is a negative number.

array = ["a", "b", "c", "d", "e"]
array.each(start: 1, count: 3) { |x| print x, " -- " }

produces:

b -- c -- d --
View source

#each_combination(size : Int = self.size, reuse = false, &) : Nil

View source

#each_combination(size : Int = self.size, reuse = false)

View source

#each_index(&) : Nil

Calls the given block once for each index in self, passing that index as a parameter.

a = ["a", "b", "c"]
a.each_index { |x| print x, " -- " }

produces:

0 -- 1 -- 2 --
View source

#each_index

Returns an Iterator for each index in self.

a = ["a", "b", "c"]
iter = a.each_index
iter.next # => 0
iter.next # => 1

The returned iterator keeps a reference to self. If the array changes, the returned values of the iterator will change as well.

View source

#each_index(*, start : Int, count : Int

Calls the given block once for count number of indices in self starting from index start, passing each index as a parameter.

Negative indices count backward from the end of the array. (-1 is the last element).

Raises IndexError if the starting index is out of range. Raises ArgumentError if count is a negative number.

array = ["a", "b", "c", "d", "e"]
array.each_index(start: -3, count: 2) { |x| print x, " -- " }

produces:

2 -- 3 --
View source

#each_permutation(size : Int = self.size, reuse = false)

Returns an Iterator over each possible permutation of size of self.

iter = [1, 2, 3].each_permutation
iter.next # => [1, 2, 3]
iter.next # => [1, 3, 2]
iter.next # => [2, 1, 3]
iter.next # => [2, 3, 1]
iter.next # => [3, 1, 2]
iter.next # => [3, 2, 1]
iter.next # => #<Iterator::Stop>

By default, a new array is created and returned for each permutation. If reuse is given, the array can be reused: if reuse is an Array, this array will be reused; if reuse if truthy, the method will create a new array and reuse it. This can be used to prevent many memory allocations when each slice of interest is to be used in a read-only fashion.

View source

#each_permutation(size : Int = self.size, reuse = false, &) : Nil

Yields each possible permutation of size of self.

a = [1, 2, 3]
sums = [] of Int32
a.each_permutation(2) { |p| sums << p.sum } # => nil
sums                                        # => [3, 4, 3, 5, 4, 5]

By default, a new array is created and yielded for each permutation. If reuse is given, the array can be reused: if reuse is an Array, this array will be reused; if reuse if truthy, the method will create a new array and reuse it. This can be used to prevent many memory allocations when each slice of interest is to be used in a read-only fashion.

View source

#each_repeated_combination(size : Int = self.size, reuse = false, &) : Nil

View source

#each_repeated_combination(size : Int = self.size, reuse = false)

View source

#empty?

Returns true if self is empty, false otherwise.

([] of Int32).empty? # => true
([1]).empty?         # => false
View source

#equals?(other : Indexable

Optimized version of equals? used when other is also an Indexable.

View source

#equals?

Determines if self equals other according to a comparison done by the given block.

If self's size is the same as other's size, this method yields elements from self and other in tandem: if the block returns true for all of them, this method returns true. Otherwise it returns false.

a = [1, 2, 3]
b = ["a", "ab", "abc"]
a.equals?(b) { |x, y| x == y.size } # => true
a.equals?(b) { |x, y| x == y }      # => false
View source

#fetch(index, default)

Returns the value at the index given by index, or when not found the value given by default.

a = [:foo, :bar]
a.fetch(0, :default_value) # => :foo
a.fetch(2, :default_value) # => :default_value
View source

#fetch(index : Int

Returns the element at the given index, if in bounds, otherwise executes the given block with the index and returns its value.

a = [:foo, :bar]
a.fetch(0) { :default_value }    # => :foo
a.fetch(2) { :default_value }    # => :default_value
a.fetch(2) { |index| index * 3 } # => 6
View source

#first

:inherited:

View source

#hash(hasher)

View source

#index(offset : Int = 0

Returns the index of the first object in self for which the block returns true, starting from the given offset, or nil if no match is found.

[1, 2, 3, 1, 2, 3].index(offset: 2) { |x| x < 2 } # => 3
View source

#index(object, offset : Int = 0)

Returns the index of the first appearance of value in self starting from the given offset, or nil if the value is not in self.

[1, 2, 3, 1, 2, 3].index(2, offset: 2) # => 4
View source

#join(separator : String | Char | Number = "")

Optimized version of Enumerable#join that performs better when all of the elements in this indexable are strings: the total string bytesize to return can be computed before creating the final string, which performs better because there's no need to do reallocations.

View source

#last

Returns the last element of self if it's not empty, or raises IndexError.

([1, 2, 3]).last   # => 3
([] of Int32).last # raises IndexError
View source

#last

Returns the last element of self if it's not empty, or the given block's value.

([1, 2, 3]).last { 4 }   # => 3
([] of Int32).last { 4 } # => 4
View source

#last?

Returns the last element of self if it's not empty, or nil.

([1, 2, 3]).last?   # => 3
([] of Int32).last? # => nil
View source

#permutations(size : Int = self.size)

Returns an Array with all possible permutations of size.

a = [1, 2, 3]
a.permutations    # => [[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
a.permutations(1) # => [[1],[2],[3]]
a.permutations(2) # => [[1,2],[1,3],[2,1],[2,3],[3,1],[3,2]]
a.permutations(3) # => [[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
a.permutations(0) # => [[]]
a.permutations(4) # => []
View source

#repeated_combinations(size : Int = self.size)

View source

#reverse_each(&) : Nil

Same as #each, but works in reverse.

View source

#reverse_each

Returns an Iterator over the elements of self in reverse order.

View source

#rindex(value, offset = size - 1)

Returns the index of the last appearance of value in self, or nil if the value is not in self.

If offset is given, it defines the position to end the search (elements beyond this point are ignored).

[1, 2, 3, 2, 3].rindex(2)            # => 3
[1, 2, 3, 2, 3].rindex(2, offset: 2) # => 1
View source

#rindex(offset = size - 1

Returns the index of the first object in self for which the block returns true, starting from the last object, or nil if no match is found.

If offset is given, the search starts from that index towards the first elements in self.

[1, 2, 3, 2, 3].rindex { |x| x < 3 }            # => 3
[1, 2, 3, 2, 3].rindex(offset: 2) { |x| x < 3 } # => 1
View source

#sample(random = Random::DEFAULT)

Optimized version of Enumerable#sample that runs in O(1) time.

a = [1, 2, 3]
a.sample                # => 3
a.sample                # => 1
a.sample(Random.new(1)) # => 2
View source

abstract #size

Returns the number of elements in this container.

View source

#to_a

Returns an Array with all the elements in the collection.

{1, 2, 3}.to_a # => [1, 2, 3]
View source

abstract #unsafe_fetch(index : Int)

Returns the element at the given index, without doing any bounds check.

Indexable makes sure to invoke this method with index in 0...size, so converting negative indices to positive ones is not needed here.

Clients never invoke this method directly. Instead, they access elements with #[](index) and #[]?(index).

This method should only be directly invoked if you are absolutely sure the index is in bounds, to avoid a bounds check for a small boost of performance.

View source

#values_at(*indexes : Int)

Returns a Tuple populated with the elements at the given indexes. Raises IndexError if any index is invalid.

["a", "b", "c", "d"].values_at(0, 2) # => {"a", "c"}
View source