reduce(...)
public
enum.reduce(initial, sym) => obj
enum.reduce(sym) => obj
enum.reduce(initial) {| memo, obj |
block } => obj enum.reduce
{| memo, obj | block } => obj
Combines all elements of <i>enum</i> by applying a binary
operation, specified by a block or a symbol that names a
method or operator.
If you specify a block, then for each element in <i>enum<i>
the block is passed an accumulator value (<i>memo</i>) and the element.
If you specify a symbol instead, then each element in the collection
will be passed to the named method of <i>memo</i>.
In either case, the result becomes the new value for <i>memo</i>.
At the end of the iteration, the final value of <i>memo</i> is the
return value fo the method.
If you do not explicitly specify an <i>initial</i> value for <i>memo</i>,
then uses the first element of collection is used as the initial value
of <i>memo</i>.
Examples:
# Sum some numbers (5..10).reduce(:+)
#=> 45 # Same using a block and inject (5..10).inject {|sum, n| sum + n }
#=> 45 # Multiply some numbers (5..10).reduce(1, :*)
#=> 151200 # Same using a block (5..10).inject(1) {|product, n| product * n }
#=> 151200 # find the longest word
longest = %w{ cat sheep bear }.inject
do |memo,word|
memo.length > word.length ? memo : word
end longest #=> “sheep”
Show source
/*
* call-seq:
* enum.inject(initial, sym) => obj
* enum.inject(sym) => obj
* enum.inject(initial) {| memo, obj | block } => obj
* enum.inject {| memo, obj | block } => obj
*
* enum.reduce(initial, sym) => obj
* enum.reduce(sym) => obj
* enum.reduce(initial) {| memo, obj | block } => obj
* enum.reduce {| memo, obj | block } => obj
*
* Combines all elements of <i>enum</i> by applying a binary
* operation, specified by a block or a symbol that names a
* method or operator.
*
* If you specify a block, then for each element in <i>enum<i>
* the block is passed an accumulator value (<i>memo</i>) and the element.
* If you specify a symbol instead, then each element in the collection
* will be passed to the named method of <i>memo</i>.
* In either case, the result becomes the new value for <i>memo</i>.
* At the end of the iteration, the final value of <i>memo</i> is the
* return value fo the method.
*
* If you do not explicitly specify an <i>initial</i> value for <i>memo</i>,
* then uses the first element of collection is used as the initial value
* of <i>memo</i>.
*
* Examples:
*
* # Sum some numbers
* (5..10).reduce(:+) #=> 45
* # Same using a block and inject
* (5..10).inject {|sum, n| sum + n } #=> 45
* # Multiply some numbers
* (5..10).reduce(1, :*) #=> 151200
* # Same using a block
* (5..10).inject(1) {|product, n| product * n } #=> 151200
* # find the longest word
* longest = %w{ cat sheep bear }.inject do |memo,word|
* memo.length > word.length ? memo : word
* end
* longest #=> "sheep"
*
*/
static VALUE
enum_inject(argc, argv, obj)
int argc;
VALUE *argv;
VALUE obj;
{
VALUE memo[2];
rb_block_call_func *iter = inject_i;
switch (rb_scan_args(argc, argv, "02", &memo[0], &memo[1])) {
case 0:
memo[0] = Qundef;
break;
case 1:
if (rb_block_given_p()) {
break;
}
memo[1] = (VALUE)rb_to_id(memo[0]);
memo[0] = Qundef;
iter = inject_op_i;
break;
case 2:
if (rb_block_given_p()) {
rb_warning("given block not used");
}
memo[1] = (VALUE)rb_to_id(memo[1]);
iter = inject_op_i;
break;
}
rb_block_call(obj, id_each, 0, 0, iter, (VALUE)memo);
if (memo[0] == Qundef) return Qnil;
return memo[0];
}