Каков наилучший способ структурировать оператор if для двух условий с действием для каждого и действием для обоих?

#logic #conditional

#Логические #условные операторы

Вопрос:

Когда у меня есть два условия, с действием для каждого условия и действием для обоих условий, если одно из них истинно,

Иногда я делаю это

 if (cond1 or cond2)
    if (cond1)
        do act 1
    if (cond2)
        do act 2
    do always
  

Иногда я делаю это

 if (cond1)
    do act 1
    do always
if (cond2)
    do act 2
    do always
  

Но я бы действительно хотел сделать это

 if (cond1)
    do act 1
or if (cond2)
    do act 2
then
    do always
  

Существует ли последний метод на каком-либо языке или существует предпочтительный метод для обработки этой ситуации?

Спасибо.

Ответ №1:

Я бы предложил следующее:

 if (cond1)
    do act 1
if (cond2)
    do act 2
if (cond1 or cond2)
   do always
  

Ответ №2:

Если вам действительно это нужно, а извлекать обычные вещи в другую функцию громоздко, вы могли бы использовать подобный макрос (непроверенный, Common Lisp):

 (defmacro cond-any (clauses)
  (let ((any-clause (gensym "any")))
    `(let ((,any-clause nil))
       (cond ,@(mapcar (lambda (clause)
                         (if (eq (first clause) :any-after)
                             (setf any-clause (rest clause))
                             (append clause any-clause)))
                       clauses)))))
  

Это дает вам возможность сделать это:

 (cond-any (:any-after do-always)
          (cond1 do-1)
          (cond2 do-2))
  

Ключевое слово :any-after тогда означает «если какое-либо из последующих условий
являются истинными, добавьте это после его части then «.

Ответ №3:

Предпочитайте что-то, что по возможности не требует дублирования кода.

Эта альтернатива может быть наиболее гибкой с минимальным дублированием:

 var := false

if (cond1)
    do act 1
    var := true

if (cond2)
    do act 2
    var := true

if (var)
    do always
  

Вы можете обнаружить, что вы хотите установить var чаще, или что с течением времени количество «если», которые вы хотите «делать всегда», растет. Этот способ позволяет избежать «сложных» операторов and / or.

Ответ №4:

 return unless (cond1 or cond2)
if (cond1)
    do_act 1
if (cond2)
    do_act 2
do_always
  

Ответ №5:

Несколько операторов If приводят к увеличению затрат времени, поскольку каждый оценивается отдельно. Чтобы избежать этого, используйте лестницу if else if для сокращения времени. Мое предложение :-

 if(cond1 AND cond2)
       do act 1
       do act 2
       do always
else if (cond1 OR cond2)
       if(cond1)
           do act 1
       else
           do act 2 
       do always
  

Во всех ваших решениях количество сравнений не менее 2. Но в этом конкретном решении минимум равен 1 . Так что в идеале это должно подходить наилучшим образом.

Комментарии:

1. Мне это не нравится. Логика не прямолинейна, дублируется много кода, и часто больший размер кода будет больше, чем одно сравнение, которое вы сохранили…