如何用红宝石中的每个代码干?

时间:2015-12-24 03:10:32

标签: ruby-on-rails ruby

我在这里:

_visits = _visits.select { |v| v.webmaster == options[:webmaster] } if options[:webmaster]
_visits = _visits.select { |v| v.country_code == options[:country_code] } if options[:country_code]
_visits = _visits.select { |v| v.created_at > options[:period].first && v.created_at < options[:period].last } if options[:period]

_leads = _leads.select { |l| l.webmaster == options[:webmaster] } if options[:webmaster]
_leads = _leads.select { |l| l.country_code == options[:country_code] } if options[:country_code]
_leads = _leads.select { |l| l.created_at > options[:period].first && l.created_at < options[:period].last } if options[:period]

如您所见,代码实际上是相同的。所以我试过了:

[ _visits, _leads ].each do |e|
  e = e.select { |_e| _e.webmaster == options[:webmaster] } if options[:webmaster]
  e = e.select { |_e| _e.country_code == options[:country_code] } if options[:country_code]
  e = e.select { |_e| _e.created_at > options[:period].first && _e.created_at < options[:period].last } if options[:period]
end

它没有用,因此ruby按值传递。这里有解决方法吗?

2 个答案:

答案 0 :(得分:3)

我认为它可以运作

_visits, _leads = [ _visits, _leads ].map do |e|
  e = e.select { |_e| _e.webmaster == options[:webmaster] } if options[:webmaster]
  e = e.select { |_e| _e.country_code == options[:country_code] } if options[:country_code]
  e.select { |_e| _e.created_at > options[:period].first && _e.created_at < options[:period].last } if options[:period]
end

答案 1 :(得分:1)

根本没有对此进行测试,但是当前答案的代码现在已经存在(通过他们自己的错误,他们只是回答你提出的问题) - 以及你的原始代码 - 将遍历两者你的潜在客户和你的访问三次。这可能性能更差,但考虑做这样的事情:

_visits, _leads = [_vists, _leads].map do |e|
  e.select do |elem|
    (options[:webmaster] ? elem.webmaster == options[:webmaster] : true)
    && (options[:country_code] ? elem.country_code == options[:country_code] : true)
    && (options[:period] ? _e.created_at > options[:period].first && _e.created_at < options[:period].last : true)
  end
end

要清理它并避免在你的选项哈希中查找很多次(不知道它会进行多少次检查或者它有多贵)你可以这样做。

webmaster    = options[:webmaster]
country_code = options[:country_code]
period       = options[:period]

_visits, _leads = [_vists, _leads].map do |e|
  e.select do |elem|
    (webmaster ? elem.webmaster == webmaster : true)
    && (country_code ? elem.country_code == country_code : true)
    && (period ? _e.created_at > period.first && _e.created_at < period.last : true)
  end
end