module Iterator(T)
Overview
AnIterator allows processing sequences lazily, as opposed toEnumerable which processes
sequences eagerly and produces anArray in most of its methods.
As an example, let's compute the first three numbers in the range1..10_000_000 that are even,
multiplied by three. One way to do this is:
(1..10_000_000).select(&.even?).map { |x| x * 3 }.first(3) # => [6, 12, 18]
The above works, but creates many intermediate arrays: one for the#select call,
one for the#map call and one for the#first call. A more efficient way is to invoke
Range#each without a block, which gives us anIterator so we can process the operations
lazily:
(1..10_000_000).each.select(&.even?).map { |x| x * 3 }.first(3) # => #< Iterator(T)::First...
Iterator redefines many ofEnumerable's method in a lazy way, returning iterators
instead of arrays.
At the end of the call chain we get back a new iterator: we need to consume it, either
using#each orEnumerable#to_a:
(1..10_000_000).each.select(&.even?).map { |x| x * 3 }.first(3).to_a # => [6, 12, 18]
Because iterators only go forward, when using methods that consume it entirely or partially –
to_a,any?,count,none?,one? andsize – subsequent calls will give a different
result as there will be less elements to consume.
iter = (0...100).each
iter.size # => 100
iter.size # => 0
Iterating step-by-step
An iterator returns its next element on the method#next.
Its return type is a union of the iterator's element type and theStop type:
T | Iterator::Stop.
The stop type is a sentinel value which indicates that the iterator has
reached its end. It usually needs to be handled and filtered out in order to
use the element value for anything useful.
UnlikeNil it's not an implicitly falsey type.
iter = (1..5).each
# Unfiltered elements contain `Iterator::Stop` type
iter.next + iter.next # Error: expected argument #1 to 'Int32#+' to be Int32, not (Int32 | Iterator::Stop)
# Type filtering eliminates the stop type
a = iter.next
b = iter.next
unless a.is_a?(Iterator::Stop) || b.is_a?(Iterator::Stop)
a + b # => 3
end
Iterator::Stop is only present in the return type of#next. All other
methods remove it from their return types.
Iterators can be used to build a loop.
iter = (1..5).each
sum = 0
while !(elem = iter.next).is_a?(Iterator::Stop)
sum += elem
end
sum # => 15
Implementing an Iterator
To implement anIterator you need to define a#next method that must return the next
element in the sequence orIterator::Stop::INSTANCE, which signals the end of the sequence
(you can invoke#stop inside an iterator as a shortcut).
For example, this is an iterator that returns a sequence ofN zeros:
class Zeros
include Iterator(Int32)
def initialize(@size : Int32)
@produced = 0
end
def next
if @produced < @size
@produced += 1
0
else
stop
end
end
end
zeros = Zeros.new(5)
zeros.to_a # => [0, 0, 0, 0, 0]
The standard library provides iterators for many classes, likeArray,Hash,Range,String andIO.
Usually to get an iterator you invoke a method that would usually yield elements to a block,
but without passing a block:Array#each,Array#each_index,Hash#each,String#each_char,
IO#each_line, etc.
Included Modules
Direct including types
Defined in:
iterator.crjson/from_json.cr
json/to_json.cr
yaml/to_yaml.cr
Constructors
-
.new(pull : JSON::PullParser)
Creates a new iterator which iterates over a JSON array.
Class Method Summary
-
.chain(iters : Iterator(Iter)) forall Iter
The same as
#chain, but have better performance when the quantity of iterators to chain is large (usually greater than 4) or undetermined. -
.chain(iters : Iterable(Iter)) forall Iter
the same as
.chain(Iterator(Iter)) -
.empty
Returns an empty iterator.
-
.from_json(string_or_io)
Reads the content of a JSON array into an iterator in a lazy way.
- .of(element : T)
- .of(&block : -> T)
-
.stop
Shortcut for
Iterator::Stop::INSTANCE, to signal that there are no more elements in an iterator.
Instance Method Summary
-
#accumulate(initial : U) forall U
Returns an iterator that returnsinitial and its prefix sums with the original iterator's elements.
-
#accumulate
Returns an iterator that returns the prefix sums of the original iterator's elements.
-
#accumulate(initial : U, &block : U, T -> U) forall U
Returns an iterator that accumulatesinitial with the original iterator's elements by the givenblock.
-
#accumulate(&block : T, T -> T)
Returns an iterator that accumulates the original iterator's elements by the givenblock.
-
#chain(other : Iterator(U)) forall U
Returns an iterator that returns elements from the original iterator until it is exhausted and then returns the elements of the second iterator.
-
#chunk(reuse = false, &block : T -> U) forall T, U
Returns an Iterator that enumerates over the items, chunking them together based on the return value of the block.
-
#chunk_while(reuse : Bool | Array(T) = false, &block : T, T -> B) forall B
Returns an iterator for each chunked elements where elements are kept in a given chunk as long as the block's value over a pair of elements istruthy.
-
#compact_map(&func : T -> _)
Returns an iterator that applies the given function to the element and then returns it unless it is
nil. -
#cons(n : Int, reuse = false)
Returns an iterator that returns consecutive chunks of the sizen.
-
#cons_pair : Iterator(Tuple(T, T))
Returns an iterator that returns consecutive pairs of adjacent items.
-
#cycle(n : Int)
Returns an iterator that repeatedly returns the elements of the original iterator starting back at the beginning when the end was reached, but onlyn times.
-
#cycle
Returns an iterator that repeatedly returns the elements of the original iterator forever starting back at the beginning when the end was reached.
- #each
-
#each(& : T -> ) : Nil
Calls the given block once for each element, passing that element as a parameter.
-
#each_slice(n, reuse = false)
Returns an iterator that then returns slices ofn elements of the initial iterator.
-
#first(n : Int)
Returns an iterator that only returns the firstn elements of the initial iterator.
-
#flat_map(&func : T -> _)
Returns a new iterator with the concatenated results of running the block once for every element in the collection.
-
#flatten
Returns an iterator that flattens nested iterators and arrays into a single iterator whose type is the union of the simple types of all of the nested iterators and arrays (and their nested iterators and arrays, and so on).
-
#in_groups_of(size : Int, filled_up_with = nil, reuse = false)
Returns an iterator that chunks the iterator's elements in arrays ofsize filling up the remaining elements if no element remains with
nilor a given optional parameter. -
#map(&func : T -> U) forall U
Returns an iterator that applies the given block to the next element and returns the result.
-
#next
Returns the next element in this iterator, or
Iterator::Stop::INSTANCEif there are no more elements. -
#reject(&func : T -> U) forall U
Returns an iterator that only returns elements for which the passed in block returns a falsey value.
-
#reject(type : U.class) forall U
Returns an iterator that only returns elements that arenot of the giventype.
-
#reject(pattern)
Returns an iterator that only returns elements where
pattern === elementdoes not hold. -
#select(&func : T -> U) forall U
Returns an iterator that only returns elements for which the passed in block returns a truthy value.
-
#select(type : U.class) forall U
Returns an iterator that only returns elements of the giventype.
-
#select(pattern)
Returns an iterator that only returns elements where
pattern === element. -
#skip(n : Int)
Returns an iterator that skips the firstn elements and only returns the elements after that.
-
#skip_while(&func : T -> U) forall U
Returns an iterator that only starts to return elements once the given block has returned falsey value for one element.
-
#slice(n : Int, reuse = false)
Alias of
#each_slice. -
#slice_after(reuse : Bool | Array(T) = false, &block : T -> B) forall B
Returns an iterator over chunks of elements, where each chunk ends rightafter the given block's value istruthy.
-
#slice_after(pattern, reuse : Bool | Array(T) = false)
Returns an iterator over chunks of elements, where each chunk ends rightafter the given pattern is matched with
pattern === element. -
#slice_before(reuse : Bool | Array(T) = false, &block : T -> B) forall B
Returns an iterator over chunks of elements, where each chunk ends rightbefore the given block's value istruthy.
-
#slice_before(pattern, reuse : Bool | Array(T) = false)
Returns an iterator over chunks of elements, where each chunk ends rightbefore the given pattern is matched with
pattern === element. -
#slice_when(reuse : Bool | Array(T) = false, &block : T, T -> B) forall B
Returns an iterator for each chunked elements where the ends of chunks are defined by the block, when the block's value over a pair of elements istruthy.
-
#step(n : Int)
Returns an iterator that only returns everynth element, starting with the first.
-
#stop
Shortcut for
Iterator::Stop::INSTANCE, to signal that there are no more elements in an iterator. -
#take_while(&func : T -> U) forall U
Returns an iterator that returns elements while the given block returns a truthy value.
-
#tap(&block : T -> )
Returns an iterator that calls the given block with the next element of the iterator when calling
#next, still returning the original element. -
#to_json(json : JSON::Builder)
Converts the content of an iterator into a JSON array in lazy way.
-
#to_yaml(yaml : YAML::Nodes::Builder)
Converts the content of an iterator to YAML.
-
#uniq
Returns an iterator that only returns unique values of the original iterator.
-
#uniq(&func : T -> U) forall U
Returns an iterator that only returns unique values of the original iterator.
-
#with_index(offset : Int = 0)
Returns an iterator that returns a
Tupleof the element and its index. -
#with_index(offset : Int = 0, &)
Yields each element in this iterator together with its index.
-
#with_object(obj)
Returns an iterator that returns a
Tupleof the element and a given object. -
#with_object(obj, &)
Yields each element in this iterator together withobj.
-
#zip(*others : Iterator) : Iterator
Returns an iterator that returns the elements of this iterator andothers traversed in tandem as
Tuples.
Instance methods inherited from module Enumerable(T)
accumulate(initial : U) : Array(U) forall Uaccumulate : 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(T)
element_type(x)
element_type
Constructor Detail
Creates a new iterator which iterates over a JSON array. See alsoIterator#from_json.
WARNING TheJSON::PullParser can't be used by anything else until the iterator is fully consumed.
Class Method Detail
The same as#chain, but have better performance when the quantity of
iterators to chain is large (usually greater than 4) or undetermined.
array_of_iters = [[1], [2, 3], [4, 5, 6]].each.map &.each
iter = Iterator(Int32).chain array_of_iters
iter.next # => 1
iter.next # => 2
iter.next # => 3
iter.next # => 4
Reads the content of a JSON array into an iterator in a lazy way. With this method it should be possible to process a huge JSON array, without the requirement that the whole array fits into memory.
The following example produces a huge file, uses a lot of CPU but should not require much memory.
File.open("/tmp/test.json", "w+") do |f|
(0..1_000_000_000).each.to_json(f)
end
File.open("/tmp/test.json", "r") do |f|
p Iterator(Int32).from_json(f).skip(1_000_000_000).to_a
end
WARNING Thestring_or_io can't be used by anything else until the iterator is fully consumed.
Shortcut forIterator::Stop::INSTANCE, to signal that there are no more elements in an iterator.
Instance Method Detail
Returns an iterator that returnsinitial and its prefix sums with the original iterator's elements.
ExpectsU to respond to the#+ method.
iter = (3..6).each.accumulate(7)
iter.next # => 7
iter.next # => 10
iter.next # => 14
iter.next # => 19
iter.next # => 25
iter.next # => Iterator::Stop::INSTANCE
Returns an iterator that returns the prefix sums of the original iterator's elements.
ExpectsT to respond to the#+ method.
iter = (3..6).each.accumulate
iter.next # => 3
iter.next # => 7
iter.next # => 12
iter.next # => 18
iter.next # => Iterator::Stop::INSTANCE
Returns an iterator that accumulatesinitial with the original iterator's elements by the givenblock.
Similar to#accumulate(&block : T, T -> T), except the initial value is
provided by an argument and needs not have the same type as the elements of
the original iterator. This initial value is returned first.
iter = [4, 3, 2].each.accumulate("X") { |x, y| x * y }
iter.next # => "X"
iter.next # => "XXXX"
iter.next # => "XXXXXXXXXXXX"
iter.next # => "XXXXXXXXXXXXXXXXXXXXXXXX"
iter.next # => Iterator::Stop::INSTANCE
Returns an iterator that accumulates the original iterator's elements by the givenblock.
For each element of the original iterator the block is passed an accumulator value and the element. The result becomes the new value for the accumulator and is then returned. The initial value for the accumulator is the first element of the original iterator.
iter = %w(the quick brown fox).each.accumulate { |x, y| "#{x}, #{y}" }
iter.next # => "the"
iter.next # => "the, quick"
iter.next # => "the, quick, brown"
iter.next # => "the, quick, brown, fox"
iter.next # => Iterator::Stop::INSTANCE
Returns an iterator that returns elements from the original iterator until
it is exhausted and then returns the elements of the second iterator.
Compared to.chain(Iterator(Iter)), it has better performance when the quantity of
iterators to chain is small (usually less than 4).
This method also cannot chain iterators in a loop, for that see.chain(Iterator(Iter)).
iter = (1..2).each.chain(('a'..'b').each)
iter.next # => 1
iter.next # => 2
iter.next # => 'a'
iter.next # => 'b'
iter.next # => Iterator::Stop::INSTANCE
Returns an Iterator that enumerates over the items, chunking them together based on the return value of the block.
Consecutive elements which return the same block value are chunked together.
For example, consecutive even numbers and odd numbers can be chunked as follows.
[3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5].chunk(&.even?).each do |even, ary|
p [even, ary]
end
# => [false, [3, 1]]
# [true, [4]]
# [false, [1, 5, 9]]
# [true, [2, 6]]
# [false, [5, 3, 5]]
The following key values have special meaning:
Enumerable::Chunk::Dropspecifies that the elements should be droppedEnumerable::Chunk::Alonespecifies that the element should be chunked by itself
By default, a new array is created and yielded for each chunk when invoking#next.
- Ifreuse is given, the array can be reused
- Ifreuse is an
Array, this array will be reused - Ifreuse is 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.
See also:Enumerable#chunks.
Returns an iterator for each chunked elements where elements are kept in a given chunk as long as the block's value over a pair of elements istruthy.
For example, one-by-one increasing subsequences can be chunked as follows:
ary = [1, 2, 4, 9, 10, 11, 12, 15, 16, 19, 20, 21]
iter = ary.chunk_while { |i, j| i + 1 == j }
iter.next # => [1, 2]
iter.next # => [4]
iter.next # => [9, 10, 11, 12]
iter.next # => [15, 16]
iter.next # => [19, 20, 21]
iter.next # => Iterator::Stop::INSTANCE
By default, a new array is created and yielded for each slice when invoking#next.
- Ifreuse is
false, the method will create a new array for each chunk - Ifreuse is
true, the method will create a new array and reuse it. - Ifreuse is an
Array, that array will be reused
This can be used to prevent many memory allocations when each slice of interest is to be used in a read-only fashion.
See also#slice_when, which works similarly but the block's condition is inverted.
Returns an iterator that applies the given function to the element and then
returns it unless it isnil. If the returned value would benil it instead
returns the next nonnil value.
iter = [1, nil, 2, nil].each.compact_map { |e| e.try &.*(2) }
iter.next # => 2
iter.next # => 4
iter.next # => Iterator::Stop::INSTANCE
Returns an iterator that returns consecutive chunks of the sizen.
iter = (1..5).each.cons(3)
iter.next # => [1, 2, 3]
iter.next # => [2, 3, 4]
iter.next # => [3, 4, 5]
iter.next # => Iterator::Stop::INSTANCE
By default, a new array is created and returned for each consecutive call of#next.
- Ifreuse is given, the array can be reused
- Ifreuse is
true, the method will create a new array and reuse it. - Ifreuse is an instance of
Array,Dequeor a similar collection type (implementing#<<,#shiftand#size) it will be used. - Ifreuse is falsey, the array will not be reused.
This can be used to prevent many memory allocations when each slice of interest is to be used in a read-only fashion.
Chunks of two items can be iterated using#cons_pair, an optimized
implementation for the special case ofn == 2 which avoids heap
allocations.
Returns an iterator that returns consecutive pairs of adjacent items.
iter = (1..5).each.cons_pair
iter.next # => {1, 2}
iter.next # => {2, 3}
iter.next # => {3, 4}
iter.next # => {4, 5}
iter.next # => Iterator::Stop::INSTANCE
Chunks of more than two items can be iterated using#cons.
This method is just an optimized implementation for the special case of
n == 2 to avoid heap allocations.
Returns an iterator that repeatedly returns the elements of the original iterator starting back at the beginning when the end was reached, but onlyn times.
iter = ["a", "b", "c"].each.cycle(2)
iter.next # => "a"
iter.next # => "b"
iter.next # => "c"
iter.next # => "a"
iter.next # => "b"
iter.next # => "c"
iter.next # => Iterator::Stop::INSTANCE
Returns an iterator that repeatedly returns the elements of the original iterator forever starting back at the beginning when the end was reached.
iter = ["a", "b", "c"].each.cycle
iter.next # => "a"
iter.next # => "b"
iter.next # => "c"
iter.next # => "a"
iter.next # => "b"
iter.next # => "c"
iter.next # => "a"
# and so an and so on
Calls the given block once for each element, passing that element as a parameter.
iter = ["a", "b", "c"].each
iter.each { |x| print x, " " } # Prints "a b c"
Returns an iterator that then returns slices ofn elements of the initial iterator.
iter = (1..9).each.each_slice(3)
iter.next # => [1, 2, 3]
iter.next # => [4, 5, 6]
iter.next # => [7, 8, 9]
iter.next # => Iterator::Stop::INSTANCE
By default, a new array is created and yielded for each consecutive when invoking#next.
- Ifreuse is given, the array can be reused
- Ifreuse is an
Array, this array will be reused - Ifreuse is 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.
Returns an iterator that only returns the firstn elements of the initial iterator.
iter = ["a", "b", "c"].each.first 2
iter.next # => "a"
iter.next # => "b"
iter.next # => Iterator::Stop::INSTANCE
Returns a new iterator with the concatenated results of running the block
once for every element in the collection.
OnlyArray andIterator results are concatenated; every other value is
returned once in the new iterator.
iter = [1, 2, 3].each.flat_map { |x| [x, x] }
iter.next # => 1
iter.next # => 1
iter.next # => 2
iter = [1, 2, 3].each.flat_map { |x| [x, x].each }
iter.to_a # => [1, 1, 2, 2, 3, 3]
Returns an iterator that flattens nested iterators and arrays into a single iterator whose type is the union of the simple types of all of the nested iterators and arrays (and their nested iterators and arrays, and so on).
iter = [(1..2).each, ('a'..'b').each].each.flatten
iter.next # => 1
iter.next # => 2
iter.next # => 'a'
iter.next # => 'b'
iter.next # => Iterator::Stop::INSTANCE
Returns an iterator that chunks the iterator's elements in arrays ofsize
filling up the remaining elements if no element remains withnil or a given
optional parameter.
iter = (1..3).each.in_groups_of(2)
iter.next # => [1, 2]
iter.next # => [3, nil]
iter.next # => Iterator::Stop::INSTANCE
iter = (1..3).each.in_groups_of(2, 'z')
iter.next # => [1, 2]
iter.next # => [3, 'z']
iter.next # => Iterator::Stop::INSTANCE
By default, a new array is created and yielded for each group.
- Ifreuse is given, the array can be reused
- Ifreuse is an
Array, this array will be reused - Ifreuse is 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.
Returns an iterator that applies the given block to the next element and returns the result.
iter = [1, 2, 3].each.map &.*(2)
iter.next # => 2
iter.next # => 4
iter.next # => 6
iter.next # => Iterator::Stop::INSTANCE
Returns the next element in this iterator, orIterator::Stop::INSTANCE if there
are no more elements.
Returns an iterator that only returns elements for which the passed in block returns a falsey value.
iter = [1, 2, 3].each.reject &.odd?
iter.next # => 2
iter.next # => Iterator::Stop::INSTANCE
Returns an iterator that only returns elements that arenot of the giventype.
iter = [1, false, 3, true].each.reject(Bool)
iter.next # => 1
iter.next # => 3
iter.next # => Iterator::Stop::INSTANCE
Returns an iterator that only returns elements
wherepattern === element does not hold.
iter = [2, 3, 1, 5, 4, 6].each.reject(3..5)
iter.next # => 2
iter.next # => 1
iter.next # => 6
iter.next # => Iterator::Stop::INSTANCE
Returns an iterator that only returns elements for which the passed in block returns a truthy value.
iter = [1, 2, 3].each.select &.odd?
iter.next # => 1
iter.next # => 3
iter.next # => Iterator::Stop::INSTANCE
Returns an iterator that only returns elements of the giventype.
iter = [1, false, 3, nil].each.select(Int32)
iter.next # => 1
iter.next # => 3
iter.next # => Iterator::Stop::INSTANCE
Returns an iterator that only returns elements
wherepattern === element.
iter = [1, 3, 2, 5, 4, 6].each.select(3..5)
iter.next # => 3
iter.next # => 5
iter.next # => 4
iter.next # => Iterator::Stop::INSTANCE
Returns an iterator that skips the firstn elements and only returns the elements after that.
iter = (1..3).each.skip(2)
iter.next # -> 3
iter.next # -> Iterator::Stop::INSTANCE
Returns an iterator that only starts to return elements once the given block has returned falsey value for one element.
iter = [1, 2, 3, 4, 0].each.skip_while { |i| i < 3 }
iter.next # => 3
iter.next # => 4
iter.next # => 0
iter.next # => Iterator::Stop::INSTANCE
Returns an iterator over chunks of elements, where each chunk ends rightafter the given block's value istruthy.
For example, to get chunks that end at each uppercase letter:
ary = ['a', 'b', 'C', 'd', 'E', 'F', 'g', 'h']
# ^ ^ ^
iter = ary.slice_after(&.uppercase?)
iter.next # => ['a', 'b', 'C']
iter.next # => ['d', 'E']
iter.next # => ['F']
iter.next # => ['g', 'h']
iter.next # => Iterator::Stop::INSTANCE
By default, a new array is created and yielded for each slice when invoking#next.
- Ifreuse is
false, the method will create a new array for each chunk - Ifreuse is
true, the method will create a new array and reuse it. - Ifreuse is an
Array, that array will be reused
This can be used to prevent many memory allocations when each slice of interest is to be used in a read-only fashion.
Returns an iterator over chunks of elements, where each
chunk ends rightafter the given pattern is matched
withpattern === element.
For example, to get chunks that end at each ASCII uppercase letter:
ary = ['a', 'b', 'C', 'd', 'E', 'F', 'g', 'h']
# ^ ^ ^
iter = ary.slice_after('A'..'Z')
iter.next # => ['a', 'b', 'C']
iter.next # => ['d', 'E']
iter.next # => ['F']
iter.next # => ['g', 'h']
iter.next # => Iterator::Stop::INSTANCE
By default, a new array is created and yielded for each slice when invoking#next.
- Ifreuse is
false, the method will create a new array for each chunk - Ifreuse is
true, the method will create a new array and reuse it. - Ifreuse is an
Array, that array will be reused
This can be used to prevent many memory allocations when each slice of interest is to be used in a read-only fashion.
Returns an iterator over chunks of elements, where each chunk ends rightbefore the given block's value istruthy.
For example, to get chunks that end just before each uppercase letter:
ary = ['a', 'b', 'C', 'd', 'E', 'F', 'g', 'h']
# ^ ^ ^
iter = ary.slice_before(&.uppercase?)
iter.next # => ['a', 'b']
iter.next # => ['C', 'd']
iter.next # => ['E']
iter.next # => ['F', 'g', 'h']
iter.next # => Iterator::Stop::INSTANCE
By default, a new array is created and yielded for each slice when invoking#next.
- Ifreuse is
false, the method will create a new array for each chunk - Ifreuse is
true, the method will create a new array and reuse it. - Ifreuse is an
Array, that array will be reused
This can be used to prevent many memory allocations when each slice of interest is to be used in a read-only fashion.
Returns an iterator over chunks of elements, where each
chunk ends rightbefore the given pattern is matched
withpattern === element.
For example, to get chunks that end just before each ASCII uppercase letter:
ary = ['a', 'b', 'C', 'd', 'E', 'F', 'g', 'h']
# ^ ^ ^
iter = ary.slice_before('A'..'Z')
iter.next # => ['a', 'b']
iter.next # => ['C', 'd']
iter.next # => ['E']
iter.next # => ['F', 'g', 'h']
iter.next # => Iterator::Stop::INSTANCE
By default, a new array is created and yielded for each slice when invoking#next.
- Ifreuse is
false, the method will create a new array for each chunk - Ifreuse is
true, the method will create a new array and reuse it. - Ifreuse is an
Array, that array will be reused
This can be used to prevent many memory allocations when each slice of interest is to be used in a read-only fashion.
Returns an iterator for each chunked elements where the ends of chunks are defined by the block, when the block's value over a pair of elements istruthy.
For example, one-by-one increasing subsequences can be chunked as follows:
ary = [1, 2, 4, 9, 10, 11, 12, 15, 16, 19, 20, 21]
iter = ary.slice_when { |i, j| i + 1 != j }
iter.next # => [1, 2]
iter.next # => [4]
iter.next # => [9, 10, 11, 12]
iter.next # => [15, 16]
iter.next # => [19, 20, 21]
iter.next # => Iterator::Stop::INSTANCE
By default, a new array is created and yielded for each slice when invoking#next.
- Ifreuse is
false, the method will create a new array for each chunk - Ifreuse is
true, the method will create a new array and reuse it. - Ifreuse is an
Array, that array will be reused
This can be used to prevent many memory allocations when each slice of interest is to be used in a read-only fashion.
See also#chunk_while, which works similarly but the block's condition is inverted.
Returns an iterator that only returns everynth element, starting with the first.
iter = (1..6).each.step(2)
iter.next # => 1
iter.next # => 3
iter.next # => 5
iter.next # => Iterator::Stop::INSTANCE
Shortcut forIterator::Stop::INSTANCE, to signal that there are no more elements in an iterator.
Returns an iterator that returns elements while the given block returns a truthy value.
iter = (1..5).each.take_while { |i| i < 3 }
iter.next # => 1
iter.next # => 2
iter.next # => Iterator::Stop::INSTANCE
Returns an iterator that calls the given block with the next element of the
iterator when calling#next, still returning the original element.
a = 0
iter = (1..3).each.tap { |x| a += x }
iter.next # => 1
a # => 1
iter.next # => 2
a # => 3
iter.next # => 3
a # => 6
iter.next # => Iterator::Stop::INSTANCE
Converts the content of an iterator into a JSON array in lazy way.
SeeIterator#from_json for an example.
Converts the content of an iterator to YAML.
The conversion is done in a lazy way.
In contrast toIterator#to_json this operation requires memory for the
for the complete YAML document
Returns an iterator that only returns unique values of the original iterator.
iter = [1, 2, 1].each.uniq
iter.next # => 1
iter.next # => 2
iter.next # => Iterator::Stop::INSTANCE
Returns an iterator that only returns unique values of the original iterator. The provided block is applied to the elements to determine the value to be checked for uniqueness.
iter = [["a", "a"], ["b", "a"], ["a", "c"]].each.uniq &.first
iter.next # => ["a", "a"]
iter.next # => ["b", "a"]
iter.next # => Iterator::Stop::INSTANCE
Returns an iterator that returns aTuple of the element and its index.
iter = (1..3).each.with_index
iter.next # => {1, 0}
iter.next # => {2, 1}
iter.next # => {3, 2}
iter.next # => Iterator::Stop::INSTANCE
Returns an iterator that returns aTuple of the element and a given object.
iter = (1..3).each.with_object("a")
iter.next # => {1, "a"}
iter.next # => {2, "a"}
iter.next # => {3, "a"}
iter.next # => Iterator::Stop::INSTANCE
Yields each element in this iterator together withobj. Returns that object.
Returns an iterator that returns the elements of this iterator andothers
traversed in tandem asTuples.
Iteration stops when any of the iterators runs out of elements.
iter1 = [4, 5, 6].each
iter2 = [7, 8, 9].each
iter3 = ['a', 'b', 'c', 'd'].each
iter = iter1.zip(iter2, iter3)
iter.next # => {4, 7, 'a'}
iter.next # => {5, 8, 'b'}
iter.next # => {6, 9, 'c'}
iter.next # => Iterator::Stop::INSTANCE