Anurag
Anurag

Reputation: 141929

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_score = current_score
end

Is there a more elegant way to write this?

Upvotes: 8

Views: 554

Answers (8)

phtrivier
phtrivier

Reputation: 13425

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)

Upvotes: 0

Mike Woodhouse
Mike Woodhouse

Reputation: 52326

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.)

Upvotes: 1

miku
miku

Reputation: 188234

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)

Upvotes: 16

OscarRyz
OscarRyz

Reputation: 199373

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()

Upvotes: 0

java_dude
java_dude

Reputation: 25

Or this way

(current_score > best_score) ? best_score = current_score : best_score

Upvotes: 0

marcgg
marcgg

Reputation: 66535

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).

Upvotes: 2

nocksock
nocksock

Reputation: 5527

Maybe a one-liner?

best_score = current_score if best_score < current_score

Upvotes: 6

Trevor
Trevor

Reputation: 6689

This can be done on a single line:

best_score = current_score if best_score < current_score

Upvotes: 15

Related Questions