Method: Enumerable#chunk_while
- Defined in:
- enum.c
#chunk_while {|elt_before, elt_after| ... } ⇒ Object
Creates an enumerator for each chunked elements. The beginnings of chunks are defined by the block.
This method splits each chunk using adjacent elements, elt_before and elt_after, in the receiver enumerator. This method split chunks between elt_before and elt_after where the block returns false.
The block is called the length of the receiver enumerator minus one.
The result enumerator yields the chunked elements as an array. So each method can be called as follows:
enum.chunk_while { |elt_before, elt_after| bool }.each { |ary| ... }
Other methods of the Enumerator class and Enumerable module, such as to_a, map, etc., are also usable.
For example, one-by-one increasing subsequence can be chunked as follows:
a = [1,2,4,9,10,11,12,15,16,19,20,21]
b = a.chunk_while {|i, j| i+1 == j }
p b.to_a #=> [[1, 2], [4], [9, 10, 11, 12], [15, 16], [19, 20, 21]]
c = b.map {|a| a.length < 3 ? a : "#{a.first}-#{a.last}" }
p c #=> [[1, 2], [4], "9-12", [15, 16], "19-21"]
d = c.join(",")
p d #=> "1,2,4,9-12,15,16,19-21"
Increasing (non-decreasing) subsequence can be chunked as follows:
a = [0, 9, 2, 2, 3, 2, 7, 5, 9, 5]
p a.chunk_while {|i, j| i <= j }.to_a
#=> [[0, 9], [2, 2, 3], [2, 7], [5, 9], [5]]
Adjacent evens and odds can be chunked as follows: (Enumerable#chunk is another way to do it.)
a = [7, 5, 9, 2, 0, 7, 9, 4, 2, 0]
p a.chunk_while {|i, j| i.even? == j.even? }.to_a
#=> [[7, 5, 9], [2, 0], [7, 9], [4, 2, 0]]
Enumerable#slice_when does the same, except splitting when the block returns true instead of false.
4567 4568 4569 4570 4571 4572 4573 4574 4575 4576 4577 4578 4579 4580 4581 4582 |
# File 'enum.c', line 4567
static VALUE
enum_chunk_while(VALUE enumerable)
{
VALUE enumerator;
VALUE pred;
pred = rb_block_proc();
enumerator = rb_obj_alloc(rb_cEnumerator);
rb_ivar_set(enumerator, id_slicewhen_enum, enumerable);
rb_ivar_set(enumerator, id_slicewhen_pred, pred);
rb_ivar_set(enumerator, id_slicewhen_inverted, Qtrue);
rb_block_call(enumerator, idInitialize, 0, 0, slicewhen_i, enumerator);
return enumerator;
}
|