# Better way for accumulating a value than using inject/reduce with conditional operator?

When there is a situation where I want to accumulate a value I see myself using inject/reduce with a conditional statement. E.g., when I want to add 1 to a value each time an element in a list has a certain value I do something like this:

puts names.reduce(0) {|acc, name| triangles.include?(name.points) ? acc+=1 : acc}

Here names is an array of names, triangles is a list of the first 30 triangle integers (1/2n(n+1)) and points is a method added to class String which calculates the integers value of each character in the name and adds them. So the point is to check how many names in the list are triangle values when you calculate the points in that way.

The issue I have is with the conditional area ([conditional] ? acc+=1 : acc). You can also rewrite the method as:

result = 0
names.each {|name| result +=1 if triangles.include?(name.points)}
puts result

But this method uses three lines and has to initialize the variable at first.

Is there a better way to keep track of the amount (e.g., result, or the acc in the inject/reduce) that does not use the conditional operator (?) or costs three lines of code?

• triangles is an array? better a structure with O(1) inclusion predicates (i.e. a set). May 17, 2014 at 18:11
• triangles is an array of integers, yes. @tokland what do you mean with a O(1) inclusion predicate/set and how would I implement this? May 18, 2014 at 21:35
• array.include?(item) is O(n) on arrays but O(1) on set. set = array.to_set and then use it for inclussion tests. May 18, 2014 at 21:49