Alternativa para múltiplas declarações if

Meu código contém muitos múltiplosif afirmações. Existe alguma outra maneira de se livrar dessas declarações. Por exemplo, suponha que eu tenha as seguintes condições

if(t1 >= 1 && t2 == 0 && t3 == 0) $('div.b_class').fadeIn();
if(t1 == 0 && t2 >= 1 && t3 == 0) $('div.c_class').fadeIn();
if(t1 == 0 && t2 == 0 && t3 == 1) $('div.d_class').fadeIn();
if(t1 && t2 >= 1 && t3 == 0) $('div.b_class.c_class').fadeIn();
if(t1 && t3 >= 1&& t2 == 0) $('div.b_class.d_class').fadeIn();

Existe alguma maneira de simplificar essas declarações?

 Ken20 de out de 2012 02:38
a linguagem mencionada aqui é a linguagem C, eu também acho que as condições podem ser facilmente simplificadas.
 Juve23 de out de 2012 20:21
@Alonso Se você está feliz com uma das respostas, por favor, marque-a como resposta aceita.
 Ken20 de out de 2012 02:43
@DrummerB eu respondi, mas eu não acho que as idéias são claras neste caso. em C o equivalente a multiple if é a instrução switch case, caso contrário eu não sei do que estamos falando aqui.
 chris20 de out de 2012 02:35
Você pode agrupar alguns, comot3 == 0.
 Aniket Inge20 de out de 2012 02:38
mesmo que as condições possam ser agrupadas, como agrupar as instruções $ ('div')?
 Alonso20 de out de 2012 07:25
sim, eles são inegers apenas com valores entre 0 e 3 apenas e mais uma coisa, eu poderia ter usado a declaração if-else-if acima, apenas uma declaração será verdadeira de cada vez a partir das declarações acima
 DrummerB20 de out de 2012 02:36
@Ken Não parece um simples switch case para mim.
 cbayram20 de out de 2012 03:09
Se você decidir ir com uma declaração de switch, não quebre as condições e mantenha seu pedido até que tenha feito algum re-fatoramento de lógica. :)
 Alonso21 de out de 2012 17:33
terá em mente da próxima vez.
 Jack20 de out de 2012 02:37
@Ken como ele deve trocar casos em condições que não são expressões? Esta não é uma linguagem funcional com correspondência de padrões :)
 Ken20 de out de 2012 02:40
neste momento eu não sei o que é esta questão ... também tudo isso se pode ser melhor organizado
 Juve21 de out de 2012 10:54
@Alonso Como você pode ver, as pessoas estão tentando adivinhar o que você realmente quer fazer. Da próxima vez, por favor, tente descrever com mais detalhes o que você realmente quer fazer e postar pedaços de código mais completos (executáveis). Não encurte muito seu problema real por causa da questão.
 Jack20 de out de 2012 02:39
@ Ken: como eu disse, esta não é uma linguagem funcional com correspondência de padrões.
 DrummerB20 de out de 2012 02:40
@Alonso Tem certeza que você quis dizert1 && t2 >= 1 no seu quartoif? Isso seria o mesmo quet1 != 0 && t2 >= 1 e a julgar pelo outroif declarações que eu acho que você queriat1 >= 1 && t2 >= 1 (que é o mesmo se você estiver usando números inteiros sem sinal, é claro).
 Ken20 de out de 2012 02:41
Que língua é essa ? por que você coloca C nas tags? Eu não entendi a questão toda.
 Alonso20 de out de 2012 02:47
Desculpe, mencionei a linguagem de programação errada. Não é 'C', é jQuery e @ken nesta questão apenas alguma lógica precisa ser implementada.
 Ken20 de out de 2012 02:50
Jquery não é uma linguagem ... talvez seja javascript. Eu não sou um especialista em javascript, então eu vou deixar isso, mas sinceramente eu não sei como você pode lidar com isso de uma forma eficiente, especialmente com uma linguagem como o javascript.
 cbayram20 de out de 2012 03:21
@Alonso o que é seguro assumir para os valores t1, t2 e t3? Podemos supor que eles serão inteiros?
 Ken20 de out de 2012 02:36
switch case ?

questionAnswers(4)

Isso deve funcionar:

var selector = 'div';
if (t1) {
    selector += '.b_class';
}
if (t2) {
    selector += '.c_class';
}
if (t3) {
    selector += '.d_class';
}
$(selector).fadeIn();

Ele se baseia nos valores "truthy / falsy" para tX (0 é falsamente, 1-3 são verdadeiros, vejahttp://11heavens.com/falsy-and-truthy-in-javascript para mais detalhes sobre "truthy / falsy").

A única ressalva a esta abordagem é que isso permiteselector ser estar'div.b_class.c_class.d_class' E set1, t2et3 são todos diferentes de zero.

E seselector não é aceitável neste caso, altere ot3 condicional aif (t3 && !(t1 || t2)).

Quando ot3 condicional é modificado paraif (t3 && !(t1 || t2)), o único jeitoselector podem terd_class acrescentado é set3 é diferente de zero e ambost1 et2 são zero.

var selector = 'div';
if (t1) {
    selector += '.b_class';
}
if (t2) {
    selector += '.c_class';
}
if (t3 && !(t1 || t2)) { //modified conditional
    selector += '.d_class';
}
$(selector).fadeIn();

ATUALIZAR:

A resposta original era para o que eu suspeitava que o OP realmente pretendia (já que o OP implica que o código é hipotético), então parabéns aJuve para detectar isso. Satisfazercbayram, isso duplicará a lógica do OP (embora eu não tenha certeza se você poderia chamar isso de "simplificado", já que ele só remove umif comparação e é substancialmente mais difícil de ler).

var selector = 'div';
if ((((t1 && !(t2 || t3)) || (t1 && t3) || (t1 && t2 && !t3))) && !(t1 && t2 && t3)) {
    selector += '.b_class';
}
if ((t2 && !(t1 || t3)) || (t1 && t2 && !t3)) {
    selector += '.c_class';
}
if ((t3 === 1 && !(t1 || t2)) || (t1 && t3 && !t2)) {
    selector += '.d_class';
}
if (selector === 'div') {
    selector = '';
}
$(selector).fadeIn();

Aqui está um violino em ação:http://jsfiddle.net/dX7AK/

 cbayram21 de out de 2012 10:04
if (t1 == 0 && t2 == 0 &&t3 == 1) $ ('div.d_class'). fadeIn ();
 cbayram21 de out de 2012 10:01
cont ... | div.b_class.c_class t1 = 1, t2 = 1, t3 = 2: FAIL | div.b_class.c_class t1 = 1, t2 = 2, t3 = 1: FALHA | div.b_class.c_class t1 = 1, t2 = 2, t3 = 2: FALHA div.b_class.d_class | div.b_class t1 = 2, t2 = 0, t3 = 1: FALHA div.b_class.d_class | div.b_classe t1 = 2, t2 = 0, t3 = 2: FALHA | div.b_class.c_class t1 = 2, t2 = 1, t3 = 1: FALHA | div.b_class.c_class t1 = 2, t2 = 1, t3 = 2: FAIL | div.b_class.c_class t1 = 2, t2 = 2, t3 = 1: FALHA | div.b_class.c_class t1 = 2, t2 = 2, t3 = 2: FAIL
 Bergi20 de out de 2012 23:38
+1. Muito bom exemplo de redução de código complexo e duplicado
 Juve21 de out de 2012 10:51
Exatamente! Essa solução "simplória" não faz o que Alonso descreve. Mas talvez o que Alonso pretendia ;-).
 cbayram21 de out de 2012 10:00
A ideia certa, mas má execução. Isso não é remotamente a mesma lógica da lógica condicional original. | div.d_classe t1 = 0, t2 = 0, t3 = 2: FALHA | div.c_class t1 = 0, t2 = 1, t3 = 1: FALHA | div.c_class t1 = 0, t2 = 1, t3 = 2: FAIL | div.c_class t1 = 0, t2 = 2, t3 = 1: FALHA | div.c_class t1 = 0, t2 = 2, t3 = 2: FALHA div.b_class.d_class | div.b_class t1 = 1, t2 = 0, t3 = 1: FALHA div.b_class.d_class | div.b_classe t1 = 1, t2 = 0, t3 = 2: FALHA | div.b_class.c_class t1 = 1, t2 = 1, t3 = 1: FAIL

ifs e seuts são inteiros fixos, e o objetivo principal é a legibilidade de suas muitas "regras". Então você pode tentar o seguinte.

Primeiro eu me certificaria de que todosts tem um valor válido e ignora os casos indefinidos. Se as variáveist são valores lógicos reais em vez de números Eu também usaria apenas regras explícitas (por exemplo,t1 == 0 ao invés de usar>, <, >=, <=), esp. se as regras que você deseja implementar são tão diversas quanto as expressas em seuif afirmações.

Então você poderia codificar a lógica usando um sistema numérico, por exemplo, usando decimais para boa legibilidade. Para cadat você usa uma posição decimal de um novo "número lógico" que codifica sua lógica:

111 means t1 == t2 == t1 == 1
201 means t1 == 2, t2 == 0, t3 == 1
etc.

O número é facilmente criado a partir do seut1,t2et3:

num = t1*100 + t2*10 + t3

O caso de switch abaixo implementa sua lógica. É uma versão desdobrada do seuif regras. Ao não permitir verificações de múltiplos valores (via>=, etc.) precisamos especificar uma regra para cada combinação que você deseja manipular. Isso pode aumentar o número ou as regras que você precisa especificar, mas também pode tornar suas regras lógicas mais legíveis e fáceis de manter.

var getFadeInClass = function(t1,t2,t3) {
    // for the sake of shortness I use ".b" instead of ".b_class" etc.
    var num = t1*100 + t2*10 + t3

    switch(logic_state){
    case 100:; case 200:; case 300: return ".b"
    case  10:; case  20:; case  30: return ".c"

    case   1:                       return ".d"

    case 110:; case 120:; case 130:;
    case 210:; case 220:; case 230:;
    case 310:; case 320:; case 330: return ".b.c"

    case 101:; case 102:; case 103:;
    case 201:; case 202:; case 203:;
    case 301:; case 302:; case 303: return ".b.d"
}
return ""

}

Você também pode usar Math ou outros tipos de teste para calcular os números.

var x = t1*100 + t2*10 + t3
if ( x != 0 && x%100    == 0)  return "b"
if ( x != 0 && x%100%10 == 0)  return "c"
if ( x == 1 )                  return "d"

Mas eu preferiria a caixa de interruptor porque, lê mais bem. Espero que isso seja o que você queria alcançar. :)

Você pode verificar uma versão em execução dessa lógica decimal emeste violino.

Felicidades, Juve

 Bergi20 de out de 2012 23:31
queswitch declaração dói.
 Juve21 de out de 2012 01:32
Eu sei, mas ele escreveu que tem "muito"if afirmações. Eu suponho que ele tem uma lógica mais complexa (desde que elets pode levar quatro valores diferentes). Para uma lógica real de quatro valores, você não pode facilmente ter uma solução muito curta e agradável de ler. Você precisa lidar com todas as diferentes possibilidades.
 Juve21 de out de 2012 17:46
Mmh, ok Eu não pensei nisso. Obrigado pela dica!
 Alonso23 de out de 2012 21:26
Obrigado Juve. Sua resposta merece um upvote. Tem uma ideia da sua resposta.
 Bergi21 de out de 2012 12:29
Ainda assim, você poderia ter usado fall-through neste caso.

t2 e t3 forem 0 a infinito positivo, a lógica modificada é um pouco condensada:

<!DOCTYPE html>
<html>
   <head>
      <script type="text/javascript">
        function orig(t1, t2, t3) {
            var hits = "";
            if(t1 >= 1 && t2 == 0 && t3 == 0) hits += 'div.b_class\n';
            if(t1 == 0 && t2 >= 1 && t3 == 0) hits += 'div.c_class\n'; 
            if(t1 == 0 && t2 == 0 && t3 == 1) hits += 'div.d_class\n';
            if(t1 && t2 >= 1 && t3 == 0) hits += 'div.b_class.c_class\n';
            if(t1 && t3 >= 1 && t2 == 0) hits += 'div.b_class.d_class\n';
            return hits;
        }
        function modified(t1, t2, t3) {
            var hits = "";
            if(t2 >= 1 && t3 == 0)
                hits += (t1 == 0)?'div.c_class\n':'div.b_class.c_class\n';
            if(t1 >= 1 && t2 == 0) 
                hits += (t3 == 0)?'div.b_class\n':'div.b_class.d_class\n';          
            if(t1 == 0 && t2 == 0 && t3 == 1)   
                hits += 'div.d_class\n';
            return hits;
        }

        function runTest() {
            for(var i = 0; i < 3; i++) {
                for(var j = 0; j < 3; j++) {
                    for(var k = 0; k < 3; k++) {                    
                        var o = orig(i, j, k);
                        var m = modified(i, j, k);
                        if(o != m)
                            console.info(o + " | " + m);
                        console.warn("t1="+i+", t2="+j+", t3="+k + ": " + ((o == m)?"PASS":"FAIL"));            
                    }       
                }       
            }       

        }
      </script>
   </head>
   <body onload="runTest()">
   </body>
</html>

Em ambos os casos, essa é uma boa maneira de testar sua modificação em relação ao original.

QuestionSolution

as como esta:

switch(true)
{
 case (t1 >= 1 && t2 == 0 && t3 == 0) : $('div.b_class').fadeIn(); break;
 case (t1 == 0 && t2 >= 1 && t3 == 0) : $('div.c_class').fadeIn(); break;
 case (t1 == 0 && t2 == 0 && t3 == 1) : $('div.d_class').fadeIn(); break;
 case (t1 && t2 >= 1 && t3 == 0)      : $('div.b_class.c_class').fadeIn(); break;
 case (t1 && t3 >= 1&& t2 == 0)       : $('div.b_class.d_class').fadeIn(); break;
}
 Alonso23 de out de 2012 21:26
Isto é o que torna meu código um pouco mais legível.
 Juve21 de out de 2012 18:08
Não se trata de simples reescrita de código. Ele está pedindo uma maneira de "simplificar"

yourAnswerToTheQuestion