Tintin81
Tintin81

Reputation: 10207

How to combine three map functions into one in Ruby on Rails?

I am trying to rewrite these three functions in a single one:

def self.net_amount_by_year(year)
  year(year).map(&:net_amount).sum
end

def self.taxable_amount_by_year(year)
  year(year).map(&:taxable_amount).sum
end

def self.gross_amount_by_year(year)
  year(year).map(&:gross_amount).sum
end

Can anybody help?

This is what I've got so far:

def self.amount_by_year(type_of_amount, year)
  year(year).map(&type_of_amount.to_sym).sum
end

The &type_of_amount bit doesn't work of course. And I wonder how to do that.

Thanks for any help.

P.S.: By the way, I don't even know what the & is for. Can anybody explain?

Upvotes: 3

Views: 97

Answers (2)

sawa
sawa

Reputation: 168121

Your code should work as is if you give it a symbol (to_sym is redundant).

def self.amount_by_year(type_of_amount, year)
  year(year).map(&type_of_amount).sum
end

type_of_amount to be passed should be either :net_amount, :taxable_amount, or :gross_amount.

If you want to compact the arguments, you can even do:

def self.amount_by_year(type, year)
  year(year).map(&:"#{type}_amount").sum
end

and pass to type either :net, :taxable, or :gross.

In fact, you can do:

def self.amount_by_year(type, year)
  year(year).sum(&:"#{type}_amount")
end

Upvotes: 2

Carlos Drew
Carlos Drew

Reputation: 1633

This should work:

def self.amount_by_year(type_of_amount, year)
  year(year).map{|y| y.send(type_of_amount)}.sum
end

In fact, you should just be able to do this:

def self.amount_by_year(type_of_amount, year)
  year(year).sum{|y| y.send(type_of_amount)}
end

References:
Ruby send method
Rails sum method

Upvotes: 2

Related Questions