最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Convert ternary conditional operators into if statements? - Stack Overflow

programmeradmin0浏览0评论

With minified code that looks like this,

f&&!f.error?k.button.b==k.button.c.G?k.button.Q(b,e,f,c,d):k.button.b==k.button.c.o&&k.button.P(b,e,f,c,d):(console.error(f),f=f.error.message||chrome.i18n.getMessage("error_tooltip"),k.button.v(b.id,f),d({action:"error"}))

Is there an automated tool that can transform that one line of conditional operators into a series of if statements?

Example 1:

From

(i < 0 ? function1() : function2())

to

if (i < 0) {
    function1();
} else {
    function2();
}

Example 2:

From

(i < 0 ? function1() : (i === 0 ? function2() : function3()))

to

if (i < 0) {
    function1();
} else {
    if (i === 0) {
        function2();
    } else {
        function3();
    }
}

With minified code that looks like this,

f&&!f.error?k.button.b==k.button.c.G?k.button.Q(b,e,f,c,d):k.button.b==k.button.c.o&&k.button.P(b,e,f,c,d):(console.error(f),f=f.error.message||chrome.i18n.getMessage("error_tooltip"),k.button.v(b.id,f),d({action:"error"}))

Is there an automated tool that can transform that one line of conditional operators into a series of if statements?

Example 1:

From

(i < 0 ? function1() : function2())

to

if (i < 0) {
    function1();
} else {
    function2();
}

Example 2:

From

(i < 0 ? function1() : (i === 0 ? function2() : function3()))

to

if (i < 0) {
    function1();
} else {
    if (i === 0) {
        function2();
    } else {
        function3();
    }
}
Share Improve this question edited Jan 17, 2012 at 10:13 XP1 asked Jan 17, 2012 at 8:13 XP1XP1 7,1838 gold badges59 silver badges63 bronze badges 3
  • 4 Can you provide a shorter example and include an example of your desired result? Also, this is hardly language agnostic, as such a tool would have to be able to parse the specific language you are using (looks like Javascript). – Björn Pollex Commented Jan 17, 2012 at 8:19
  • Possible duplicate of: stackoverflow.com/questions/822119/… – ldiqual Commented Jan 17, 2012 at 9:22
  • 1 @ldiqual, none of those formatters transform conditional operators into if statements. They just add spaces. – XP1 Commented Jan 17, 2012 at 10:15
Add a comment  | 

2 Answers 2

Reset to default 12

From

f&&!f.error?k.button.b==k.button.c.G?k.button.Q(b,e,f,c,d):k.button.b==k.button.c.o&&k.button.P(b,e,f,c,d):(console.error(f),f=f.error.message||chrome.i18n.getMessage("error_tooltip"),k.button.v(b.id,f),d({action:"error"}))

to

if (f && !f.error)
{
    if (k.button.b == k.button.c.G)
    {
        k.button.Q(b, e, f, c, d)
    }
    else
    {
        k.button.b == k.button.c.o && k.button.P(b, e, f, c, d)
    }
}
else
{
    (console.error(f), f = f.error.message || chrome.i18n.getMessage("error_tooltip"), k.button.v(b.id, f), d(
    {
        action: "error"
    }))
}

using this (and then JSBeautifier):

/*jslint browser: true, vars: true, white: true, maxerr: 50, indent: 4 */
(function (console)
{
    "use strict";

    function transform(string)
    {
        var questionMark = string.indexOf("?");
        var colon = string.indexOf(":", questionMark);

        if (questionMark === -1 || colon === -1)
        {
            return string;
        }

        var condition = string.substring(0, questionMark);
        var expressions = string.substring(questionMark + 1, string.length);
        var trueExpression = null;
        var falseExpression = null;

        console.log("expressions: " + expressions);

        // While looking in pairs, find the location where the colon occurs before the question mark.
        questionMark = expressions.indexOf("?");
        colon = expressions.indexOf(":");
        while ((questionMark !== -1 && colon !== -1) && (questionMark < colon))
        {
            questionMark = expressions.indexOf("?", questionMark + 1);
            colon = expressions.indexOf(":", colon + 1);
        }

        console.log("\t" + "questionMark: " + questionMark);
        console.log("\t" + "colon: " + colon);

        trueExpression = expressions.substring(0, colon);
        falseExpression = expressions.substring(colon + 1, expressions.length);

        console.log("condition: " + condition);
        console.log("trueExpression: " + trueExpression);
        console.log("falseExpression: " + falseExpression);

        console.log("-");

        return ("if (" + condition + ") {\n" + transform(trueExpression) + "\n} else {\n" + transform(falseExpression) + "\n}");
    }

    function unittest()
    {
        console.log(transform("(i < 0 ? function1() : function2())"));
        console.log("---");
        console.log(transform("i < 0 ? function1() : function2()"));
        console.log("---");
        console.log(transform("i < 0 ? function1() : i === 0 ? function2() : function3()"));
        console.log("---");
        console.log(transform("i > 0 ? i === 1 ? function1() : function2() : function3()"));
        console.log("---");
        console.log(transform("i > 0 ? i === 1 ? function1() : i === 2 ? function2() : function3() : function4()"));
        console.log("---");
        console.log(transform("i > 0 ? i === 1 ? function1() : i === 2 ? function2() : function3() : i === 0 ? function4() : function5()"));
        console.log("---");
        console.log(transform("f&&!f.error?k.button.b==k.button.c.G?k.button.Q(b,e,f,c,d):k.button.b==k.button.c.o&&k.button.P(b,e,f,c,d):(console.error(f),f=f.error.message||chrome.i18n.getMessage(\"error_tooltip\"),k.button.v(b.id,f),d({action:\"error\"}))"));
    }

    unittest();
}(window.console));

babel-plugin-transform-ternary-to-if-else

I don't know if it is too late, this question is five years old after all.

I ran into the exact same problem yesterday, and managed to put up a babel plugin to transform conditional expressions into if-else statements. It has a pretty straight-forward name: babel-plugin-transform-ternary-to-if-else

Important: I did say expressions and statements, we will get back to them later.

Examples

Here I take the two example code as input, and run them with the plugin.

// case 0: input
(i < 0 ? function1() : function2())

// case 0: output
(function () {
  if (i < 0) {
    return function1();
  }

  return function2();
})();

// case 1: input
(i < 0 ? function1() : (i === 0 ? function2() : function3()))

// case 1: output
(function () {
  if (i < 0) {
    return function1();
  }

  return function () {
    if (i === 0) {
      return function2();
    }

    return function3();
  }();
})();

Great?

You may think: Mmmm... Not so much. What's with all these IIFEs (Immediately Invoked Function Expressions)?

IIFEs

IIFEs are actually needed. Because, as I stated at the beginning, a conditional expression is an expression, an if statement is a statement.

An expression can be part of a statement, that's for sure. But can a statement become part of another statement? No it can not, unless wrapped inside an IIFE.

Of course, as a special case, a simple expression statement can be replaced with another if statement, e.g. a1() ? a2() : a3(); can be replace with if (a1()) {a2();} else {a3();}. But this can't apply to all the cases.

So, here we are, IIFEs.

The future

Good news is, when the do expressions proposal make it into the ECMAScript spec, we will go without the verbosity of IIFEs.

In fact, babel-plugin-syntax-do-expressions transforms do expressions into conditional expressions, meaning they are the exact replacement of each other.

Links

babel-plugin-transform-ternary-to-if-else

do expressions proposal

babel-plugin-syntax-do-expressions

发布评论

评论列表(0)

  1. 暂无评论