开发者

More elegant way to do this in Ruby

I've started with Ruby and am finding new, shorter, elegant ways to write code everyday.

In solving Project Euler problems, I've written a lot of code like

if best_score < current_score
  best_sco开发者_如何学Gore = current_score
end

Is there a more elegant way to write this?


best_score = [best_score, current_score].max

see: Enumerable.max


disclaimer: although this is a little more readable (imho), it's less performant:

require 'benchmark'

best_score, current_score, n = 1000, 2000, 100_000

Benchmark.bm do |x|
  x.report { n.times do best_score = [best_score, current_score].max end }
  x.report { n.times do 
    best_score = current_score if best_score < current_score 
  end }
end

will result in (with ruby 1.8.6 (2008-08-11 patchlevel 287)):

    user     system      total        real
0.160000   0.000000   0.160000 (  0.160333)
0.030000   0.000000   0.030000 (  0.030578)


This can be done on a single line:

best_score = current_score if best_score < current_score


Maybe a one-liner?

best_score = current_score if best_score < current_score


This is elegant enough. It's readable and easy to maintain.

If you want shorter, you can go:

best_score = current_score if best_score < current_score

or

best_score = current_score unless best_score >= current_score

... but it's not necessarily an improvement in all cases (keep in mind readability).


Since I can't see it above, I lean toward this use of the ternary operator:

best_score = current_score > best_score ? current_score : best_score

and there's also this rather less frequently-encountered version:

best_score = (best_score > current_score && best_score) || current_score

...which is harder to read, but shows a (to me) slightly unexpected side-effect of short-circuiting. (See this blog post.)


Or this way

(current_score > best_score) ? best_score = current_score : best_score


It looks just fine the way you have it already. I would only change the comparison so it reads:

If current score is greater than best score

You may also create a method and call that. That's more OO to me.

 def get_best_score() 
      current_score > best_score ?
          current_score :
          best_score
 end

This is what OOP is all about isn't? Hold the object state.

best_score = get_best_score()


Not sure it would qualify as "more elegant", but if you don't want to rewrite the if every time ...

def max(b,c)
 if (b < c)
  c
 else
  b
 end
end

best = 10 
current = 20
best = max(best,current)
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜