Более элегантный способ сделать это в Ruby - PullRequest
8 голосов
/ 21 декабря 2009

Я начал с Ruby и каждый день нахожу новые, более короткие и элегантные способы написания кода.

При решении задач Project Euler я написал много кода, подобного

if best_score < current_score
  best_score = current_score
end

Есть ли более элегантный способ написать это?

Ответы [ 8 ]

16 голосов
/ 21 декабря 2009
best_score = [best_score, current_score].max

см .: перечислим. макс.


отказ от ответственности: хотя это немного более читабельно (imho), оно менее производительно:

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

приведет к (с 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)
15 голосов
/ 21 декабря 2009

Это можно сделать в одной строке:

best_score = current_score if best_score < current_score
6 голосов
/ 21 декабря 2009

Может быть однострочник?

best_score = current_score if best_score < current_score
2 голосов
/ 21 декабря 2009

Это достаточно элегантно. Он читабелен и прост в обслуживании.

Если вы хотите короче, вы можете пойти:

best_score = current_score if best_score < current_score

или

best_score = current_score unless best_score >= current_score

... но это не обязательно улучшение во всех случаях (имейте в виду читабельность).

1 голос
/ 21 декабря 2009

Так как я не могу видеть это выше, я склоняюсь к этому использованию троичного оператора :

best_score = current_score > best_score ? current_score : best_score

и есть также эта довольно редко встречающаяся версия:

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

... который труднее читать, но показывает (для меня) немного неожиданный побочный эффект короткого замыкания. (См. это сообщение в блоге .)

0 голосов
/ 21 декабря 2009

Выглядит просто отлично, как у вас уже есть. Я бы только изменил сравнение, чтобы оно звучало так:

Если текущая оценка превышает лучшую оценку

Вы также можете создать метод и вызвать его. Это больше ОО для меня.

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

Это то, чем является ООП, не так ли? Удерживать состояние объекта.

best_score = get_best_score()
0 голосов
/ 21 декабря 2009

Или вот так

(current_score > best_score) ? best_score = current_score : best_score
0 голосов
/ 21 декабря 2009

Не уверен, что это будет считаться "более элегантным", но если вы не хотите переписывать if каждый раз ...

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

best = 10 
current = 20
best = max(best,current)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...