Reputation: 3191
So in Python sum([])
will yield 0, which is pretty important.
Whereas in ruby [].reduce(:+)
will give nil, of course the ternary operator isn't a replacement, because:
(my_complicated_mapping).empty? ? 0 : (my_complicated_mapping).reduce(:+)
Will call my_complicated_mapping
twice. Therefore the obvious method is:
res = my_complicated_mapping
res = (res.empty? ? 0 : res.reduce(:+))
I think there must be a neater way to do this though.
Upvotes: 1
Views: 96
Reputation: 66263
With reduce you can specify the initial value as the first parameter e.g.
my_complicated_mapping.reduce(0, :+)
then if the list is empty you'll get 0 instead of nil
. You can check the different alternative ways of using reduce
here.
or if using a block for reduce
it would be:
my_complicated_mapping.reduce(0) { |sum, n| sum + n }
i.e. a single parameter with with initial value and supplying your block.
It's important to understand why reduce
returns nil
in the case of the empty array: If you don't specify an explicit initial value for memo, then the first element of the array is used as the initial value of memo, which of course doesn't exist in the empty case.
Upvotes: 4
Reputation: 8821
You also can use inject
:
my_complicated_mapping.inject(0) { |sum, e| sum + e }
Upvotes: 0
Reputation: 16506
You can use to_i
to convert nil
to 0
[].reduce(:+).to_i
# => 0
Incase Array contains float values, using to_f
can help:
[].reduce(:+).to_f
# => 0.0
Upvotes: 2
Reputation: 2134
Why not give 0 as initial parameter? Like
my_complicated_mapping.reduce(0, :+)
Upvotes: 1