How to simplify ternary expressions in Javascript I have an expression that could be expressed as either of :



a += (A ? B ? x : C ? y : D : D);

a += (A &amp;&amp; B ? x : A &amp;&amp; C ? y : D);


where A,B,C are expressions of 5-10 bytes each, and x and y are single character literals (3-4 bytes). D is another chain of ternaries (without the branching problem).

I'm getting stuck trying to eliminate the duplication of D or A. If I was using if, it would be something like this:

if (A)
    if (B)
        x
    else if (C)
        y
else D


Obviously I could do ((z=A) &amp;&amp; B ? x : z &amp;&amp; C ? y : D)...but any other more creative suggestions?

The actual code looks something like:

if (r%4&lt;2&amp;&amp;r&gt;3&amp;&amp;c&lt;22&amp;&amp;c&gt;1)
    if ((i-r)%8==6)
        '\\'
    else if ((i+r)%8==1)
        '/'
else


D is something like:

(i+r) % 8 == 3 ? '/' : 
    (c-r+16) % 8 == 4 ? '\\' :
If you know that x and y cannot contain falsy values, as your code examples suggest, you can do the following to eliminate duplicate evaluation of A or D:

a += A &amp;&amp; (B &amp;&amp; x || C &amp;&amp; y) || D;


Demo code and test cases in the following snippet:



// return x
test(1,1,0); // A and B
test(1,1,1); // A and B (and C)

// return y
test(1,0,1); // A and C

// return D
test(0,0,0); // 
test(0,0,1); // C
test(0,1,0); // B
test(0,1,1); // B and C
test(1,0,0); // A


function test(A, B, C) {
  var x = 'x', y = 'y', D = 'D';
  a = A &amp;&amp; (B &amp;&amp; x || C &amp;&amp; y) || D;
  expected = (A &amp;&amp; B ? x : A &amp;&amp; C ? y : D);
  var ws = ' ';
  console.log(
    [
      A &amp;&amp; 'A' || ws, 
      B &amp;&amp; 'B' || ws, 
      C &amp;&amp; 'C' || ws
    ].join(ws),
    ' ==&gt; a = ' + a,
    a === expected ? 
      'Passed' : 
      'Failed, expected ' + expected
  );
}




Otherwise, if falsy values are possible, you could do this:

a += [D, x, y][A &amp;&amp; (B &amp;&amp; 1 || C &amp;&amp; 2) || 0];


Demo code and test cases in the following snippet:



// return x
test(1,1,0); // A and B
test(1,1,1); // A and B (and C)

// return y
test(1,0,1); // A and C

// return D
test(0,0,0); // 
test(0,0,1); // C
test(0,1,0); // B
test(0,1,1); // B and C
test(1,0,0); // A


function test(A, B, C) {
  var x = false, y = 0, D = '';
  A = !!A; B = !!B; C = !!C;
  a = [D, x, y][A &amp;&amp; (B &amp;&amp; 1 || C &amp;&amp; 2) || 0];
  expected = (A &amp;&amp; B ? x : A &amp;&amp; C ? y : D);
  var ws = ' ';
  console.log(
    [
      A &amp;&amp; 'A' || ws, 
      B &amp;&amp; 'B' || ws, 
      C &amp;&amp; 'C' || ws
    ].join(ws),
    ' ==&gt; a = ' + xyD(a, x, y, D),
    a === expected ? 
      'Passed' : 
      'Failed, expected ' + xyD(expected, x, y, D)
  );
}

function xyD(result, x, y, D) {
  return result === x ? 'x' :
         result === y ? 'y' :
         result === D ? 'D' : '&lt;error&gt;' ;
}