将三元条件运算符转换为 if 语句?

Posted

技术标签:

【中文标题】将三元条件运算符转换为 if 语句?【英文标题】:Convert ternary conditional operators into if statements? 【发布时间】:2012-02-12 01:42:41 【问题描述】:

使用看起来像这样的缩小代码,

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"))

是否有一种自动化工具可以将那一行条件运算符转换为一系列 if 语句?

示例 1:

来自

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

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

示例 2:

来自

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

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

【问题讨论】:

你能提供一个更简短的例子,并包括一个你想要的结果的例子吗?此外,这几乎与语言无关,因为这样的工具必须能够解析您正在使用的特定语言(看起来像 javascript)。 可能重复:***.com/questions/822119/… @ldiqual,这些格式化程序都没有将条件运算符转换为 if 语句。他们只是添加空格。 【参考方案1】:

来自

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"))

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"
    ))

使用这个(然后是 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));

【讨论】:

请在某个网站上托管这个!【参考方案2】:

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

不知道是不是太晚了,这个问题毕竟有五年了。

我昨天遇到了完全相同的问题,并设法建立了一个 babel 插件来将条件表达式转换为 if-else 语句。它有一个非常直接的名称:babel-plugin-transform-ternary-to-if-else

重要提示:我确实说过表达式陈述,我们稍后会回复它们。

示例

这里我将两个示例代码作为输入,并使用插件运行它们。

// 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();
  ();
)();

很棒?

你可能会想:嗯……没那么多。所有这些IIFE(立即调用函数表达式)是怎么回事?

IIFE

实际上需要 IIFE。因为,正如我在开头所说的,条件表达式是表达式,if 语句是语句。

表达式可以是语句的一部分,这是肯定的。但是一个语句可以成为另一个语句的一部分吗? 不可以,除非包裹在 IIFE 中

当然,作为一种特殊情况,一个简单的表达式语句可以替换为另一个 if 语句,例如a1() ? a2() : a3(); 可以替换为 if (a1()) a2(); else a3();。但这并不适用于所有情况。

所以,我们来了,IIFE。

未来

好消息是,当do expressions proposal 成为 ECMAScript 规范时,我们将不再像 IIFE 那样冗长。

事实上,babel-plugin-syntax-do-expressions 转换了do expressions into conditional expressions,这意味着它们是彼此完全替换

链接

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

do expressions proposal

babel-plugin-syntax-do-expressions

【讨论】:

以上是关于将三元条件运算符转换为 if 语句?的主要内容,如果未能解决你的问题,请参考以下文章

java 选择结构if

python条件(三元)运算符

三元运算符

Python中的三元运算符是如何实现的

三元条件运算符中的多个条件?

条件选择