Method: Enumerable#sum
- Defined in:
- enum.c
#sum(initial_value = 0) ⇒ Numeric #sum(initial_value = 0) {|element| ... } ⇒ Object
With no block given, returns the sum of initial_value and the elements:
(1..100).sum # => 5050
(1..100).sum(1) # => 5051
('a'..'d').sum('foo') # => "fooabcd"
Generally, the sum is computed using methods + and each; for performance optimizations, those methods may not be used, and so any redefinition of those methods may not have effect here.
One such optimization: When possible, computes using Gauss’s summation formula n(n+1)/2:
100 * (100 + 1) / 2 # => 5050
With a block given, calls the block with each element; returns the sum of initial_value and the block return values:
(1..4).sum {|i| i*i } # => 30
(1..4).sum(100) {|i| i*i } # => 130
h = {a: 0, b: 1, c: 2, d: 3, e: 4, f: 5}
h.sum {|key, value| value.odd? ? value : 0 } # => 9
('a'..'f').sum('x') {|c| c < 'd' ? c : '' } # => "xabc"
4806 4807 4808 4809 4810 4811 4812 4813 4814 4815 4816 4817 4818 4819 4820 4821 4822 4823 4824 4825 4826 4827 4828 4829 4830 4831 4832 4833 4834 4835 4836 4837 4838 4839 4840 4841 4842 4843 4844 4845 4846 4847 4848 4849 4850 4851 4852 |
# File 'enum.c', line 4806 static VALUE enum_sum(int argc, VALUE* argv, VALUE obj) { struct enum_sum_memo memo; VALUE beg, end; int excl; memo.v = (rb_check_arity(argc, 0, 1) == 0) ? LONG2FIX(0) : argv[0]; memo.block_given = rb_block_given_p(); memo.n = 0; memo.r = Qundef; if ((memo.float_value = RB_FLOAT_TYPE_P(memo.v))) { memo.f = RFLOAT_VALUE(memo.v); memo.c = 0.0; } else { memo.f = 0.0; memo.c = 0.0; } if (RTEST(rb_range_values(obj, &beg, &end, &excl))) { if (!memo.block_given && !memo.float_value && (FIXNUM_P(beg) || RB_BIGNUM_TYPE_P(beg)) && (FIXNUM_P(end) || RB_BIGNUM_TYPE_P(end))) { return int_range_sum(beg, end, excl, memo.v); } } if (RB_TYPE_P(obj, T_HASH) && rb_method_basic_definition_p(CLASS_OF(obj), id_each)) hash_sum(obj, &memo); else rb_block_call(obj, id_each, 0, 0, enum_sum_i, (VALUE)&memo); if (memo.float_value) { return DBL2NUM(memo.f + memo.c); } else { if (memo.n != 0) memo.v = rb_fix_plus(LONG2FIX(memo.n), memo.v); if (!UNDEF_P(memo.r)) { memo.v = rb_rational_plus(memo.r, memo.v); } return memo.v; } } |