ruby inject with conditional in block? ruby inject with conditional in block? ruby ruby

ruby inject with conditional in block?


inject passes the result of the block through to the next iteration as the first argument. Your block will return nil when your if statement is false, which then gets passed back in as sum.

To get the correct answer, the block should return the current sum when it's false:

1.upto(999).inject(0) { |sum, i| (0 == i%3 || 0 ==  i%5) ? sum + i : sum }


Complementary answer: if you're about to tackle Euler problems you should start to build your own extensions of reusable code. In this case, the first extension would be Enumerable#sum:

module Enumerable  def sum    inject(0, :+)  endend

And now you can write a solution that separates the condition of the summatory (you can read it out loud and it makes sense, that's typical of functional/declarative style):

1.upto(999).select { |x| x % 3 == 0 || x % 5 == 0 }.sum

You could even push it one step further and create Fixnum#divisible_by? so you can write:

1.upto(999).select { |x| x.divisible_by?(3) || x.divisible_by?(5) }.sum

More: here it's not a problem, but later on strict implementations (those using arrays) will require too much memory. Try then with laziness:

require 'lazy'1.upto(999).lazy.select { |x| x % 3 == 0 || x % 5 == 0 }.sum


1.upto(999).inject(0) { |sum, i| sum += i if 0 == i%3 || 0 ==  i%5; sum }

Would also work (note the +=).