Range
type Range
A span between two bounds, written (1..10) or ('a'..'z').
A range stores its endpoints on both backends without building a list. Integer and character ranges can be enumerated with both ends included. Float ranges describe continuous bounds, for example (-1.0..1.0) for random sampling; they cannot be enumerated without an explicit step.
(1..5).items # => [1, 2, 3, 4, 5]
(1..5).sum # => 15
5.in?(1..10) # => true
('a'..'e').items # => ['a', 'b', 'c', 'd', 'e']
It is Enumerable and Foldable, so the traversal methods work directly, and the list operations below answer in list terms. Use items when you want a real list to hand to something else.
(1..10).items.filter(~even?) # => [2, 4, 6, 8, 10]
(1..3).items.each { |n| IO.printLine(n) }
Implements Enumerable, Foldable.
Methods
reduce Enumerable Foldable
reduce(acc: A, f: (A -> B -> A)) -> A
Folds over the range's elements in ascending order.
This is Range's Enumerable primitive; the traversal methods are built on it. A range stays structurally minimal, so the fold runs over its materialized items.
Parameters
acc- the initial accumulator
f- combines the accumulator with each element
Returns the final accumulator
Examples
(1..4).reduce(0) { |sum, n| sum + n } # => 10
sum
Returns the sum of the range's elements.
Returns Number — the sum
Examples
(1..10).sum # => 55
(1..1).sum # => 1
product
Returns the product of the range's elements.
Returns Number — the product
Examples
(1..5).product # => 120 (five factorial)
contains?
contains?(value: A) -> Bool
Returns true when value falls inside the range, endpoints included.
5.in?(1..10) says the same thing from the value's side, and often reads better.
Parameters
value- the value to test
Returns true when the value is in range
Examples
(1..10).contains?(5) # => true
(1..10).contains?(11) # => false
items
items : [A]
Returns the range's elements as a list.
This is where a range stops being two numbers and becomes real data, so it is also where a very large range starts to cost something.
Returns the elements, in ascending order
Examples
(1..3).items # => [1, 2, 3]
('a'..'c').items # => ['a', 'b', 'c']
Building a lookup table
(1..12).items.map { |m| (m, monthName(m)) }
first
first : A?
Returns the first element, or None for an empty range.
The list operations, over the materialized items. A range is an ordered collection, so (1..5).first and (1..5).length operate on its materialized elements. Floating bounds do not define such a collection.
Returns the first element, or None
Examples
(3..7).first # => Just(3)
second
second : A?
Returns the second element, or None when the range is shorter than two.
Returns the second element, or None
Examples
(3..7).second # => Just(4)
third
third : A?
Returns the third element, or None when the range is shorter than three.
Returns the third element, or None
Examples
(3..7).third # => Just(5)
last
last : A?
Returns the last element, or None for an empty range.
Returns the last element, or None
Examples
(3..7).last # => Just(7)
rest
rest : [A]
Returns every element after the first, as a list.
Returns the remaining elements
Examples
(1..4).rest # => [2, 3, 4]
length
length : Integer
Returns how many elements the range has.
Returns the number of elements
Examples
(1..10).length # => 10
(5..5).length # => 1
count Foldable
count : Integer
Returns how many elements the range has. The same as length.
Returns the number of elements
Examples
(1..10).count # => 10
empty?
empty? : Bool
Returns true when the range has no elements.
Returns true for an empty range
Examples
(1..3).empty? # => false
max
max : A?
Returns the largest element, or None for an empty range.
Returns the largest element, or None
Examples
(1..10).max # => Just(10)
min
min : A?
Returns the smallest element, or None for an empty range.
Returns the smallest element, or None
Examples
(1..10).min # => Just(1)
reverse
reverse : [A]
Returns the elements as a list, in descending order.
Returns the elements, reversed
Examples
(1..4).reverse # => [4, 3, 2, 1]
Counting down
(1..3).reverse.each { |n| IO.printLine(n) } # prints 3, 2, 1
sort
sort : [A]
Returns the elements as a sorted list. A range is already ascending, so this is the identity: it exists so that generic code can call it.
Returns the elements, sorted
Examples
(1..4).sort # => [1, 2, 3, 4]
sort(comparator: (A -> A -> Bool)) -> [A]
Returns the elements as a list, ordered by comparator.
Parameters
comparatortruewhen the first should come first
Returns the sorted elements
Examples
(1..4).sort { |a, b| a > b } # => [4, 3, 2, 1]
uniq
uniq : [A]
Returns the elements as a list with duplicates removed. A range has none, so this is the identity: it exists so that generic code can call it.
Returns the distinct elements
Examples
(1..3).uniq # => [1, 2, 3]
join
join(separator: String) -> String
Renders the elements as text, with separator between them.
Parameters
separator- placed between elements
Returns the joined text
Examples
(1..4).join(", ") # => "1, 2, 3, 4"
A comma-separated header
"columns: ${(1..3).join(",")}" # => "columns: 1,2,3"
at
at(index: Integer) -> A?
Returns the element at index index, counting from 0, or None when out of range.
Note that the index counts positions, not values: (10..20).at(0) is Just(10).
Parameters
index- the 0-based position
Returns the element, or None
Examples
(10..20).at(0) # => Just(10)
(10..20).at(99) # => None
get
get(index: Integer) -> A?
get(index: Integer, fallback: A) -> A
Returns the element at index index, counting from 0, or None when out of range. The same as at, named to match List and Map.
Parameters
index- the 0-based position
Returns the element, or None
Examples
(10..20).get(0) # => Just(10)
(10..20).get(99) # => None
take
take(n: Integer) -> [A]
Returns the first n elements as a list.
Parameters
n- how many elements to keep
Returns the leading elements
Examples
(1..10).take(3) # => [1, 2, 3]
drop
drop(n: Integer) -> [A]
Returns everything after the first n elements, as a list.
Parameters
n- how many elements to skip
Returns the remaining elements
Examples
(1..5).drop(3) # => [4, 5]
indexOf
indexOf(value: A) -> Integer?
Returns the position of value in the range, or None when it is not in it.
Parameters
value- the element to look for
Returns the 0-based position, or None
Examples
('a'..'e').indexOf('c') # => Just(2)
(10..20).indexOf(12) # => Just(2)
zip
zip(other: [B]) -> [(A, B)]
Pairs each element with the element at the same position in other, stopping at the shorter of the two.
Parameters
other- the list to pair with
Returns the pairs, in order
Examples
(1..3).zip(["a", "b", "c"]) # => [(1, "a"), (2, "b"), (3, "c")]
Numbering a list
(1..names.count).zip(names)
partition
partition(pred: (A -> Bool)) -> ([A], [A])
Splits the elements into those satisfying pred and those that do not.
Parameters
pred- the test applied to each element
Returns the matching and non-matching elements
Examples
(1..4).partition { |n| n.even? } # => ([2, 4], [1, 3])
push
push(value: A) -> [A]
Returns the elements as a list with value added at the end.
Parameters
value- the element to add
Returns the elements plus value
Examples
(1..3).push(4) # => [1, 2, 3, 4]
From Enumerable
map- Applies
fto each item and collects the results into a list. mapIndexed- Applies
fto each item and its 0-based position, and collects the results into a list. filter- Returns the items for which
predanswerstrue. flatMap- Applies
fto each item, expecting a list back, and concatenates the results into one flat list. collect- Applies
fto each item, expecting anOptionalback, and returns the values that were present: unwrapped.
From Foldable
each- Calls
fwith each item, for its side effects. eachIndexed- Calls
fwith each item and its 0-based position, for its side effects. all?- Returns
truewhen every item satisfiespred. any?- Returns
truewhen at least one item satisfiespred. find- Returns the first item satisfying
pred, orNonewhen nothing does.