NAME
Sidef::Types::Range::Range - Range class for representing sequences of values
DESCRIPTION
The Range class implements a lazy sequence of values between two endpoints. Ranges are memory-efficient as they don't store all values but generate them on demand. They support arithmetic operations, iteration, and functional programming methods.
A range can be created using the range operator .. or by calling the Range constructor. Ranges are commonly used in loops, array slicing, and generating sequences.
SYNOPSIS
# Create a range from 1 to 10
var r = (1..10)
# Iterate over range
(1..10).each { |n|
say n
}
# Range with custom step
var evens = (0..20 `by` 2)
# Infinite ranges
var infinite = (1..Inf)
# Map over a range
var squares = (1..5).map { |n| n**2 }
# Filter range values
var odds = (1..20).grep { .is_odd }
# Range arithmetic
var r1 = (1..5)
var r2 = (10..15)
say (r1 + r2) # Add ranges
METHODS
*
a * b
Multiplies the range by a scalar value or another range. When multiplying by a scalar, each element in the range is multiplied. When multiplying by another range, performs element-wise multiplication.
say ((1..5) * 2) #=> Range(2, 4, 6, 8, 10)
say ((1..3) * (2..4)) #=> Range(2, 6, 12)
Aliases: mul
+
a + b
Adds a scalar value or another range to the range. When adding a scalar, adds it to each element. When adding another range, performs element-wise addition.
say ((1..5) + 10) #=> Range(11, 12, 13, 14, 15)
say ((1..3) + (5..7)) #=> Range(6, 8, 10)
Aliases: add
-
a - b
Subtracts a scalar value or another range from the range. When subtracting a scalar, subtracts it from each element. When subtracting another range, performs element-wise subtraction.
say ((10..15) - 5) #=> Range(5, 6, 7, 8, 9, 10)
say ((10..12) - (1..3)) #=> Range(9, 10, 11)
Aliases: sub
...
a ... b
Converts the range to a list (array) containing all values in the range. This forces evaluation of the lazy range.
var arr = (1..5)...
say arr #=> [1, 2, 3, 4, 5]
Aliases: to_list
/
a / b
Divides the range by a scalar value or another range. When dividing by a scalar, divides each element. When dividing by another range, performs element-wise division.
say ((10..20 `by` 5) / 2) #=> Range(5, 7.5, 10)
say ((10..30 `by` 10) / (2..4)) #=> Range(5, 10, 15)
Aliases: ÷, div
==
a == b
Checks if two ranges are equal. Ranges are equal if they have the same bounds, step, and direction.
say ((1..10) == (1..10)) #=> true
say ((1..10) == (1..20)) #=> false
say ((1..10 `by` 2) == (1..10)) #=> false
Aliases: eq
≠
a ≠ b
Checks if two ranges are not equal. Returns true if the ranges differ in bounds, step, or direction.
say ((1..10) ≠ (1..20)) #=> true
say ((1..10) ≠ (1..10)) #=> false
Aliases: !=, ne
accumulate
self.accumulate(block)
Returns an array of accumulated values by applying the given block (or operator) cumulatively. Similar to a running sum or cumulative operation.
say (1..5).accumulate { |a, b| a + b } #=> [1, 3, 6, 10, 15]
say (1..4).accumulate { |a, b| a * b } #=> [1, 2, 6, 24]
accumulate_by
self.accumulate_by(block)
Returns an array of accumulated values by applying the given block to each element first, then accumulating.
say (1..5).accumulate_by { |n| n**2 } #=> [1, 5, 14, 30, 55]
all
self.all(block)
Returns true if all elements in the range satisfy the condition in the block. Returns false otherwise.
say (1..10).all { |n| n > 0 } #=> true
say (1..10).all { |n| n.is_even } #=> false
any
self.any(block)
Returns true if at least one element in the range satisfies the condition in the block. Returns false if none do.
say (1..10).any { |n| n > 5 } #=> true
say (1..10).any { |n| n > 20 } #=> false
say (1..10).any { |n| n.is_even } #=> true
bounds
self.bounds
Returns an array containing the start and end bounds of the range.
say (1..10).bounds #=> [1, 10]
say (5..1).bounds #=> [5, 1]
say (0..100 `by` 5).bounds #=> [0, 100]
by
self.by(step)
Creates a new range with the specified step size. This allows you to skip values in the sequence.
say (1..10 `by` 2)... #=> [1, 3, 5, 7, 9]
say (0..20 `by` 5)... #=> [0, 5, 10, 15, 20]
say (10..1 `by` -2)... #=> [10, 8, 6, 4, 2]
cons
self.cons(n, block)
Maps over consecutive groups of n elements from the range. Returns an array of results from applying the block to each consecutive group.
say (1..10).cons(3) { |*group| group.sum } #=> [6, 9, 12, 15, 18, 21, 24, 27]
Aliases: map_cons
contain
self.contain(value)
Checks if the range contains the specified value. Takes into account the range's bounds, step, and direction.
say (1..10).contain(5) #=> true
say (1..10).contain(15) #=> false
say (1..10 `by` 2).contain(3) #=> false
say (1..10 `by` 2).contain(5) #=> true
Aliases: include, contains, includes
count
self.count(arg)
Counts elements in the range that match the given value or satisfy the given block condition.
say (1..10).count(5) #=> 1
say (1..10).count { |n| n.is_even } #=> 5
say (1..20).count { |n| n.is_prime } #=> 8
count_by
self.count_by(block)
Returns a hash with counts of elements grouped by the result of applying the block to each element.
say (1..10).count_by { |n| n % 3 }
#=> Hash(0 => 3, 1 => 4, 2 => 3)
say (1..10).count_by { |n| n.is_even ? "even" : "odd" }
#=> Hash("even" => 5, "odd" => 5)
cross_operator
self.cross_operator(*args)
Performs a cross product operation with other ranges or arrays, applying an operator to combinations.
say (1..3).cross_operator('+', 10..12)
#=> [[11, 12, 13], [12, 13, 14], [13, 14, 15]]
each_cons
self.each_cons(n, block)
Iterates over consecutive groups of n elements, passing each group to the block. Similar to cons but doesn't collect results.
(1..10).each_cons(3) { |*group|
say group
}
# Prints: [1, 2, 3], [2, 3, 4], [3, 4, 5], ...
each_slice
self.each_slice(n, block)
Iterates over the range in slices of n elements, passing each slice to the block.
(1..10).each_slice(3) { |*slice|
say slice
}
# Prints: [1, 2, 3], [4, 5, 6], [7, 8, 9], [10]
first_by
self.first_by(block)
Returns the first element for which the block returns true, or nil if no element satisfies the condition.
say (1..100).first_by { |n| n > 50 && n.is_prime } #=> 53
say (1..10).first_by { |n| n > 100 } #=> nil
flip
self.flip
Returns a new range with reversed bounds (flips the direction of iteration).
say (1..10).flip... #=> [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
say (5..1).flip... #=> [1, 2, 3, 4, 5]
Aliases: reverse
for
self.for(block)
Iterates over each element in the range, passing it to the block. This is the standard iteration method.
(1..5).for { |n|
say n
}
# Prints: 1, 2, 3, 4, 5
Aliases: each, foreach
from
self.from(from)
Creates a new range starting from the specified value, keeping the original end bound.
say (1..10).from(5)... #=> [5, 6, 7, 8, 9, 10]
grep
self.grep(block)
Filters the range, returning an array of elements that satisfy the condition in the block.
say (1..20).grep { |n| n.is_prime } #=> [2, 3, 5, 7, 11, 13, 17, 19]
say (1..10).grep { |n| n > 5 } #=> [6, 7, 8, 9, 10]
Aliases: select
head
self.head(num)
Returns an array containing the first num elements of the range.
say (1..100).head(5) #=> [1, 2, 3, 4, 5]
say (10..1).head(3) #=> [10, 9, 8]
Aliases: first
join
self.join(sep)
Converts the range to a string with elements joined by the specified separator.
say (1..5).join(', ') #=> "1, 2, 3, 4, 5"
say (1..3).join(' + ') #=> "1 + 2 + 3"
kv
self.kv
Returns an array of [index, value] pairs for each element in the range.
say (10..13).kv #=> [[0, 10], [1, 11], [2, 12], [3, 13]]
Aliases: pairs, zip_indices
last
self.last(num)
Returns an array containing the last num elements of the range.
say (1..10).last(3) #=> [8, 9, 10]
Aliases: tail
last_by
self.last_by(block)
Returns the last element for which the block returns true, or nil if no element satisfies the condition.
say (1..100).last_by { |n| n < 50 && n.is_prime } #=> 47
say (1..10).last_by { |n| n > 100 } #=> nil
len
self.len
Returns the number of elements in the range.
say (1..10).len #=> 10
say (0..20 `by` 5).len #=> 5
say (10..1).len #=> 10
Aliases: length
map
self.map(block)
Transforms each element in the range using the given block, returning an array of results.
say (1..5).map { |n| n**2 } #=> [1, 4, 9, 16, 25]
say (1..3).map { |n| n * 10 } #=> [10, 20, 30]
map_operator
self.map_operator(op, *args)
Maps an operator over the range with additional arguments.
say (1..5).map_operator('+', 10) #=> [11, 12, 13, 14, 15]
say (1..5).map_operator('**', 2) #=> [1, 4, 9, 16, 25]
max
self.max(block)
Returns the maximum element in the range. With a block, compares elements using the block's return value.
say (1..10).max #=> 10
say (1..10).max { |a, b| b <=> a } #=> 1 (reverse order)
max_by
self.max_by(block)
Returns the element that produces the maximum value when passed through the block.
say (-5..5).max_by { |n| n.abs } #=> -5 or 5
say (1..10).max_by { |n| n % 3 } #=> 2 (or 5 or 8)
min
self.min(block)
Returns the minimum element in the range. With a block, compares elements using the block's return value.
say (1..10).min #=> 1
say (1..10).min { |a, b| b <=> a } #=> 10 (reverse order)
min_by
self.min_by(block)
Returns the element that produces the minimum value when passed through the block.
say (-5..5).min_by { |n| n.abs } #=> 0
say (1..10).min_by { |n| -n } #=> 10
neg
self.neg
Returns a new range with all elements negated.
say (1..5).neg... #=> [-1, -2, -3, -4, -5]
say (-3..3).neg... #=> [3, 2, 1, 0, -1, -2, -3]
new
Range.new(from, to, step)
Creates a new range object with the specified start, end, and optional step values.
var r1 = Range.new(1, 10)
var r2 = Range.new(0, 20, 2)
var r3 = Range(5, 1, -1)
Aliases: call
none
self.none(block)
Returns true if no elements in the range satisfy the condition in the block.
say (1..10).none { |n| n > 20 } #=> true
say (1..10).none { |n| n > 5 } #=> false
pam_operator
self.pam_operator(op, *args)
Applies the pam operator (parallel map) over the range elements.
say (1..5).pam_operator('+', 10)
pick
self.pick(n)
Returns n random elements from the range without replacement. If n is not specified, returns one random element.
say (1..10).pick #=> (random number from 1 to 10)
say (1..10).pick(3) #=> [random 3 numbers, e.g., [7, 2, 9]]
rand
self.rand(n)
Returns n random elements from the range with replacement. Each call can return duplicate values.
say (1..10).rand #=> (random number from 1 to 10)
say (1..10).rand(5) #=> [5 random numbers, may contain duplicates]
Aliases: sample
reduce
self.reduce(op, initial)
Reduces the range to a single value by applying the given operator or block cumulatively. The initial value is optional.
say (1..5).reduce { |a, b| a + b } #=> 15
say (1..4).reduce { |a, b| a * b } #=> 24
say (1..10).reduce('+') #=> 55
say (1..5).reduce('+', 100) #=> 115
reduce_operator
self.reduce_operator(op, initial)
Reduces the range using a named operator. Similar to reduce but takes an operator name as a string.
say (1..10).reduce_operator('+') #=> 55
say (1..4).reduce_operator('*') #=> 24
shuffle
self.shuffle
Returns an array with the range elements in random order.
say (1..10).shuffle #=> [random permutation, e.g., [3, 7, 1, 9, 2, 5, 10, 4, 8, 6]]
slices
self.slices(n, block)
Maps over slices of n elements, applying the block to each slice and returning an array of results.
say (1..10).slices(3) { |*slice| slice.sum }
#=> [6, 15, 24, 10]
Aliases: map_slice
sort
self.sort(block)
Returns a sorted array of the range elements. With a block, uses the block for custom comparison.
say (1..10).sort { |a, b| b <=> a } #=> [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
sort_by
self.sort_by(block)
Returns an array sorted by the value returned from applying the block to each element.
say (-5..5).sort_by { |n| n.abs } #=> [0, -1, 1, -2, 2, -3, 3, -4, 4, -5, 5]
say (1..10).sort_by { |n| -n } #=> [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
step
self.step
Returns the step size of the range. For ranges created without an explicit step, returns 1 or -1 depending on direction.
say (1..10).step #=> 1
say (0..20 `by` 5).step #=> 5
say (10..1).step #=> -1
to
self.to(to)
Creates a new range with the specified end bound, keeping the original start bound.
say (1..5).to(10)... #=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
to_a
self.to_a
Converts the range to an array containing all its elements. Forces evaluation of the lazy range.
say (1..5).to_a #=> [1, 2, 3, 4, 5]
Aliases: to_array
to_v
self.to_v
Converts the range to a vector (Vector object).
var vec = (1..5).to_v
Aliases: to_vec, to_vector
unroll_operator
self.unroll_operator(op, *args)
Applies an unroll operator operation over the range.
say (1..5).unroll_operator('+', 10)
while
self.while(block)
Iterates over the range while the block condition is true, returning an array of elements.
say (1..100).while { |n| n < 10 } #=> [1, 2, 3, 4, 5, 6, 7, 8, 9]
zip_operator
self.zip_operator(op, *args)
Zips the range with other ranges or arrays, applying an operator to corresponding elements.
say (1..3).zip_operator('+', 10..12) #=> [11, 13, 15]
SEE ALSO
Sidef::Types::Array::Array, Sidef::Types::Number::Number
AUTHOR
Daniel Șuteu (trizen)