Class: Enumerator::ArithmeticSequence
| Relationships & Source Files | |
| Super Chains via Extension / Inclusion / Inheritance | |
|
Class Chain:
self,
::Enumerator
|
|
|
Instance Chain:
self,
::Enumerator,
::Enumerable
|
|
| Inherits: |
Enumerator
|
| Defined in: | enumerator.c, enumerator.c |
Overview
ArithmeticSequence is a subclass of ::Enumerator, that is a representation of sequences of numbers with common difference. Instances of this class can be generated by the Range#step and Numeric#step methods.
Class Method Summary
::Enumerator - Inherited
| .new | Creates a new |
| .produce | Creates an infinite enumerator from any block, just called over and over. |
Instance Attribute Summary
- #exclude_end? ⇒ Boolean readonly
Instance Method Summary
-
#==(obj) ⇒ Boolean
(also: #===, #eql?)
Returns
trueonly ifobjis anArithmeticSequence, has equivalent begin, end, step, and exclude_end? settings. -
#===(obj) ⇒ Boolean
Alias for #==.
- #begin
- #end
-
#eql?(obj) ⇒ Boolean
Alias for #==.
-
#first ⇒ Numeric?
Returns the first number in this arithmetic sequence, or an array of the first
nelements. -
#hash ⇒ Integer
Compute a hash-value for this arithmetic sequence.
-
#last ⇒ Numeric?
Returns the last number in this arithmetic sequence, or an array of the last
nelements. - #step
::Enumerator - Inherited
| #+ | Returns an enumerator object generated from this enumerator and a given enumerable. |
| #each | Iterates over the block according to how this |
| #each_with_index | Same as #with_index(0), i.e. there is no starting offset. |
| #each_with_object | Alias for #with_object. |
| #feed | Sets the value to be returned by the next yield inside |
| #inspect | Creates a printable version of e. |
| #next | Returns the next object in the enumerator, and move the internal position forward. |
| #next_values | Returns the next object as an array in the enumerator, and move the internal position forward. |
| #peek | Returns the next object in the enumerator, but doesn’t move the internal position forward. |
| #peek_values | Returns the next object as an array, similar to #next_values, but doesn’t move the internal position forward. |
| #rewind | Rewinds the enumeration sequence to the beginning. |
| #size | Returns the size of the enumerator, or |
| #with_index | Iterates the given block for each element with an index, which starts from |
| #with_object | Iterates the given block for each element with an arbitrary object, |
| #initialize_copy | |
::Enumerable - Included
| #all? | Passes each element of the collection to the given block. |
| #any? | Passes each element of the collection to the given block. |
| #chain | Returns an enumerator object generated from this enumerator and given enumerables. |
| #chunk | Enumerates over the items, chunking them together based on the return value of the block. |
| #chunk_while | Creates an enumerator for each chunked elements. |
| #collect | Alias for Enumerable#map. |
| #collect_concat | Alias for Enumerable#flat_map. |
| #count | Returns the number of items in |
| #cycle | Calls block for each element of enum repeatedly n times or forever if none or |
| #detect | Alias for Enumerable#find. |
| #drop | Drops first n elements from enum, and returns rest elements in an array. |
| #drop_while | Drops elements up to, but not including, the first element for which the block returns |
| #each_cons | Iterates the given block for each array of consecutive <n> elements. |
| #each_entry | Calls block once for each element in |
| #each_slice | Iterates the given block for each slice of <n> elements. |
| #each_with_index | Calls block with two arguments, the item and its index, for each item in enum. |
| #each_with_object | Iterates the given block for each element with an arbitrary object given, and returns the initially given object. |
| #entries | Alias for Enumerable#to_a. |
| #filter | Returns an array containing all elements of |
| #filter_map | Returns a new array containing the truthy results (everything except |
| #find | Passes each entry in enum to block. |
| #find_all | Alias for Enumerable#filter. |
| #find_index | Compares each entry in enum with value or passes to block. |
| #first | Returns the first element, or the first |
| #flat_map | Returns a new array with the concatenated results of running block once for every element in enum. |
| #grep | Returns an array of every element in enum for which |
| #grep_v | Inverted version of Enumerable#grep. |
| #group_by | Groups the collection by result of the block. |
| #include? | Alias for Enumerable#member?. |
| #inject | Combines all elements of enum by applying a binary operation, specified by a block or a symbol that names a method or operator. |
| #lazy | Returns an |
| #map | Returns a new array with the results of running block once for every element in enum. |
| #max | Returns the object in enum with the maximum value. |
| #max_by | Returns the object in enum that gives the maximum value from the given block. |
| #member? | Returns |
| #min | Returns the object in enum with the minimum value. |
| #min_by | Returns the object in enum that gives the minimum value from the given block. |
| #minmax | Returns a two element array which contains the minimum and the maximum value in the enumerable. |
| #minmax_by | Returns a two element array containing the objects in enum that correspond to the minimum and maximum values respectively from the given block. |
| #none? | Passes each element of the collection to the given block. |
| #one? | Passes each element of the collection to the given block. |
| #partition | Returns two arrays, the first containing the elements of enum for which the block evaluates to true, the second containing the rest. |
| #reduce | Alias for Enumerable#inject. |
| #reject | Returns an array for all elements of |
| #reverse_each | Builds a temporary array and traverses that array in reverse order. |
| #select | Alias for Enumerable#filter. |
| #slice_after | Creates an enumerator for each chunked elements. |
| #slice_before | Creates an enumerator for each chunked elements. |
| #slice_when | Creates an enumerator for each chunked elements. |
| #sort | Returns an array containing the items in enum sorted. |
| #sort_by | Sorts enum using a set of keys generated by mapping the values in enum through the given block. |
| #sum | Returns the sum of elements in an |
| #take | Returns first n elements from enum. |
| #take_while | Passes elements to the block until the block returns |
| #tally | Tallies the collection, i.e., counts the occurrences of each element. |
| #to_a | Returns an array containing the items in enum. |
| #to_h | Returns the result of interpreting enum as a list of |
| #uniq | Returns a new array by removing duplicate values in |
| #zip | Takes one element from enum and merges corresponding elements from each args. |
Constructor Details
This class inherits a constructor from Enumerator
Instance Attribute Details
#exclude_end? ⇒ Boolean (readonly)
[ GitHub ]
Instance Method Details
#==(obj) ⇒ Boolean Also known as: #===, #eql?
Returns true only if obj is an ArithmeticSequence, has equivalent begin, end, step, and exclude_end? settings.
# File 'enumerator.c', line 3761
static VALUE
arith_seq_eq(VALUE self, VALUE other)
{
if (!RTEST(rb_obj_is_kind_of(other, rb_cArithSeq))) {
return Qfalse;
}
if (!rb_equal(arith_seq_begin(self), arith_seq_begin(other))) {
return Qfalse;
}
if (!rb_equal(arith_seq_end(self), arith_seq_end(other))) {
return Qfalse;
}
if (!rb_equal(arith_seq_step(self), arith_seq_step(other))) {
return Qfalse;
}
if (arith_seq_exclude_end_p(self) != arith_seq_exclude_end_p(other)) {
return Qfalse;
}
return Qtrue;
}
#==(obj) ⇒ Boolean
#===(obj) ⇒ Boolean
Boolean
#===(obj) ⇒ Boolean
Alias for #==.
#begin
[ GitHub ]#end
[ GitHub ]
#==(obj) ⇒ Boolean
#eql?(obj) ⇒ Boolean
Boolean
#eql?(obj) ⇒ Boolean
Alias for #==.
Returns the first number in this arithmetic sequence, or an array of the first n elements.
# File 'enumerator.c', line 3402
static VALUE
arith_seq_first(int argc, VALUE *argv, VALUE self)
{
VALUE b, e, s, ary;
long n;
int x;
rb_check_arity(argc, 0, 1);
b = arith_seq_begin(self);
e = arith_seq_end(self);
s = arith_seq_step(self);
if (argc == 0) {
if (NIL_P(b)) {
return Qnil;
}
if (!NIL_P(e)) {
VALUE zero = INT2FIX(0);
int r = rb_cmpint(rb_num_coerce_cmp(s, zero, idCmp), s, zero);
if (r > 0 && RTEST(rb_funcall(b, '>', 1, e))) {
return Qnil;
}
if (r < 0 && RTEST(rb_funcall(b, '<', 1, e))) {
return Qnil;
}
}
return b;
}
// TODO: the following code should be extracted as arith_seq_take
n = NUM2LONG(argv[0]);
if (n < 0) {
rb_raise(rb_eArgError, "attempt to take negative size");
}
if (n == 0) {
return rb_ary_new_capa(0);
}
x = arith_seq_exclude_end_p(self);
if (FIXNUM_P(b) && NIL_P(e) && FIXNUM_P(s)) {
long i = FIX2LONG(b), unit = FIX2LONG(s);
ary = rb_ary_new_capa(n);
while (n > 0 && FIXABLE(i)) {
rb_ary_push(ary, LONG2FIX(i));
i += unit; // FIXABLE + FIXABLE never overflow;
--n;
}
if (n > 0) {
b = LONG2NUM(i);
while (n > 0) {
rb_ary_push(ary, b);
b = rb_big_plus(b, s);
--n;
}
}
return ary;
}
else if (FIXNUM_P(b) && FIXNUM_P(e) && FIXNUM_P(s)) {
long i = FIX2LONG(b);
long end = FIX2LONG(e);
long unit = FIX2LONG(s);
long len;
if (unit >= 0) {
if (!x) end += 1;
len = end - i;
if (len < 0) len = 0;
ary = rb_ary_new_capa((n < len) ? n : len);
while (n > 0 && i < end) {
rb_ary_push(ary, LONG2FIX(i));
if (i + unit < i) break;
i += unit;
--n;
}
}
else {
if (!x) end -= 1;
len = i - end;
if (len < 0) len = 0;
ary = rb_ary_new_capa((n < len) ? n : len);
while (n > 0 && i > end) {
rb_ary_push(ary, LONG2FIX(i));
if (i + unit > i) break;
i += unit;
--n;
}
}
return ary;
}
else if (RB_FLOAT_TYPE_P(b) || RB_FLOAT_TYPE_P(e) || RB_FLOAT_TYPE_P(s)) {
/* generate values like ruby_float_step */
double unit = NUM2DBL(s);
double beg = NUM2DBL(b);
double end = NIL_P(e) ? (unit < 0 ? -1 : 1)*HUGE_VAL : NUM2DBL(e);
double len = ruby_float_step_size(beg, end, unit, x);
long i;
if (n > len)
n = (long)len;
if (isinf(unit)) {
if (len > 0) {
ary = rb_ary_new_capa(1);
rb_ary_push(ary, DBL2NUM(beg));
}
else {
ary = rb_ary_new_capa(0);
}
}
else if (unit == 0) {
VALUE val = DBL2NUM(beg);
ary = rb_ary_new_capa(n);
for (i = 0; i < len; ++i) {
rb_ary_push(ary, val);
}
}
else {
ary = rb_ary_new_capa(n);
for (i = 0; i < n; ++i) {
double d = i*unit+beg;
if (unit >= 0 ? end < d : d < end) d = end;
rb_ary_push(ary, DBL2NUM(d));
}
}
return ary;
}
return rb_call_super(argc, argv);
}
#hash ⇒ Integer
Compute a hash-value for this arithmetic sequence. Two arithmetic sequences with same begin, end, step, and exclude_end? values will generate the same hash-value.
See also Object#hash.
# File 'enumerator.c', line 3797
static VALUE
arith_seq_hash(VALUE self)
{
st_index_t hash;
VALUE v;
hash = rb_hash_start(arith_seq_exclude_end_p(self));
v = rb_hash(arith_seq_begin(self));
hash = rb_hash_uint(hash, NUM2LONG(v));
v = rb_hash(arith_seq_end(self));
hash = rb_hash_uint(hash, NUM2LONG(v));
v = rb_hash(arith_seq_step(self));
hash = rb_hash_uint(hash, NUM2LONG(v));
hash = rb_hash_end(hash);
return ST2FIX(hash);
}
Returns the last number in this arithmetic sequence, or an array of the last n elements.
# File 'enumerator.c', line 3628
static VALUE
arith_seq_last(int argc, VALUE *argv, VALUE self)
{
VALUE b, e, s, len_1, len, last, nv, ary;
int last_is_adjusted;
long n;
e = arith_seq_end(self);
if (NIL_P(e)) {
rb_raise(rb_eRangeError,
"cannot get the last element of endless arithmetic sequence");
}
b = arith_seq_begin(self);
s = arith_seq_step(self);
len_1 = num_idiv(num_minus(e, b), s);
if (rb_num_negative_int_p(len_1)) {
if (argc == 0) {
return Qnil;
}
return rb_ary_new_capa(0);
}
last = num_plus(b, num_mul(s, len_1));
if ((last_is_adjusted = arith_seq_exclude_end_p(self) && rb_equal(last, e))) {
last = num_minus(last, s);
}
if (argc == 0) {
return last;
}
if (last_is_adjusted) {
len = len_1;
}
else {
len = rb_int_plus(len_1, INT2FIX(1));
}
rb_scan_args(argc, argv, "1", &nv);
if (!RB_INTEGER_TYPE_P(nv)) {
nv = rb_to_int(nv);
}
if (RTEST(rb_int_gt(nv, len))) {
nv = len;
}
n = NUM2LONG(nv);
if (n < 0) {
rb_raise(rb_eArgError, "negative array size");
}
ary = rb_ary_new_capa(n);
b = rb_int_minus(last, rb_int_mul(s, nv));
while (n) {
b = rb_int_plus(b, s);
rb_ary_push(ary, b);
--n;
}
return ary;
}