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 enum 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 enum<i> the
block is passed an accumulator value (<i>memo) and the element.
If you specify a symbol instead, then each element in the collection will
be passed to the named method of memo. In either case, the result
becomes the new value for memo. At the end of the iteration, the
final value of memo is the return value fo the method.
If you do not explicitly specify an initial value for
memo, then uses the first
element of collection is used as the initial value of memo.
Examples:
(5..10).reduce(:+)
(5..10).inject {|sum, n| sum + n }
(5..10).reduce(1, :*)
(5..10).inject(1) {|product, n| product * n }
longest = %w{ cat sheep bear }.inject do |memo,word|
memo.length > word.length ? memo : word
end
longest
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];
}