Ruby: Как писать вложенные ifs кратко? - PullRequest
1 голос
/ 22 февраля 2020

Есть ли более краткий способ написать следующие вложенные условия?

def sort_column
  if Product.column_names.include?(params[:sort])
    if params[:sort] == "price_latest" || params[:sort] == "price_average"
      "#{params[:sort]}->'#{cookies[:store_id]}'"
    else
      params[:sort]
    end
  else
    "name"
  end
end

Ответы [ 3 ]

2 голосов
/ 22 февраля 2020

Вы можете заменить условия if-else условным выражением, изменяя оператор в зависимости от случая (if, unless):

def sort_column
  sort = params[:sort]
  return 'name' unless Product.column_names.include?(sort)
  return "#{sort}->'#{cookies[:store_id]}'" if sort.in?(%w[price_latest price_average])

  sort
end

С помощью return name unless ... вы избавляетесь от if Product.column_names.include?(params[:sort]) else ... end.

С помощью sort.in?(%w[price_latest price_average]) вы сокращаете условие params[:sort] == "price_latest" || params[:sort] == "price_average" и возвращаете #{sort}->'#{cookies[:store_id]}'", только если оно возвращает true.

Если ни одно из других условий не выполняется оценивается как true, возвращает только значение params[:sort].

1 голос
/ 22 февраля 2020

С ранним return и case.

def sort_column
  return "name" unless Product.column_names.include?(params[:sort])

  case params[:sort]
  when "price_latest", "price_average"
    "#{params[:sort]}->'#{cookies[:store_id]}'"
  else
    params[:sort]
  end
end
0 голосов
/ 23 февраля 2020

Требуется линейный поиск, чтобы определить, содержит ли Product.column_names данный элемент. Если этот массив большой и не изменится во время выполнения кода, и sort_column должен вызываться несколько раз, производительность можно улучшить, преобразовав этот массив в набор. Определение того, содержит ли набор заданный элемент, выполняется очень быстро, время поиска сопоставимо с тем, которое требуется для определения, имеет ли га sh данный ключ.

require 'set'
names_set = Product.column_names.to_set

def sort_column(params, names_set)
  ps = params[:sort]
  return "name" unless names_set.include?(ps)
  ["price_latest", "price_average"].include?(ps) ? 
    "#{ps}->'#{cookies[:store_id]}'" : "home"
end
...