ruby inject with conditional in block?

Tonys picture Tonys · May 23, 2012 · Viewed 8.7k times · Source

doing the first Project Euler question: summing the multiples of 3 and 5 between 1 and 1000, I came up with this (pretty simple)

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

but I thought this would work but it doesn't, can someone show me what I'm doing wrong, or why it doesn't work?

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

thanks!

Answer

spike picture spike · May 23, 2012

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 }