简体   繁体   English

如何避免在复杂的布尔表达式上三元

[英]How to avoid ternary on complicated boolean expression

In linting my Javascript, I ran across a no-unneeded-ternary warning on a complex ternary option of mine. 在整理我的Javascript时,我遇到了关于我的复杂三元选项的no-unneeded-ternary警告。

I know how to solve this on simple boolean expressions: 我知道如何在简单的布尔表达式上解决此问题:

var obvious = (1 === 1) ? true : false;
// can simply become:
var obvious = (1 === 1);

However, on my below boolean expression, I don't know how to properly narrow this down without fear of breaking something which happens to be very complicated: 但是,在下面的布尔表达式中,我不知道如何适当缩小范围,而又不担心会碰巧很复杂的东西:

const include =
  (options.directory && file !== '.') ? false :
  (!dotted) ? true :
  (dotted && options.all) ? true :
  (dotted && !implied && options.almostall) ? true :
  (options.directory && file === '.') ? true :
  false;

What would be the proper shorthand implementation of this? 适当的简写实现是什么?


Taking a stab at it: 刺中它:

const include = !(options.directory && file !== '.') || 
  (!dotted) || 
  (dotted && options.all) ||
  (dotted && !implied && options.almostall) ||
  (options.directory && file === '.');

Is this correct? 这个对吗?

When you write code using a bunch of chained ternary operators, it becomes more terse and typically less readable. 当您使用一堆链式三元运算符编写代码时,它会变得更简洁且可读性更差。

const include =
  (options.directory && file !== '.') ? false :
  (!dotted) ? true :
  (dotted && options.all) ? true :
  (dotted && !implied && options.almostall) ? true :
  (options.directory && file === '.') ? true :
  false;

To break this down, I will first expand it using a module pattern: 为了解决这个问题,我将首先使用模块模式对其进行扩展:

include = (function () {
    //set up some simple names for concepts:
    var directory = options.directory;
    var isDot = file === '.';
    var all = options.all;
    var almost = options.almostall;

    if (directory && !isDot)
        return false;

    if (!dotted)
        return true;

    if (dotted && all)
        return true;

    if (dotted && implied && almost)
        return true;

    if (directory && isDot)
        return true;

    return false;
}());

This can be simplified. 这可以简化。 After checking !dotted , dotted must be true, and becomes redundant: 在检查!dotteddotted必须为true,并且变得多余:

 true && a 

converts to: 转换为:

 a 
include = (function () {
    //set up some simple names for concepts:
    var directory = options.directory;
    var isDot = file === '.';
    var all = options.all;
    var almost = options.almostall;

    if (directory && !isDot)
        return false;

    if (!dotted)
        return true;

    if (all)
        return true;

    if (implied && almost)
        return true;

    if (directory && isDot)
        return true;

    return false;
}());

As a matter of leaving well enough alone, you could feel free to stop here knowing that the code is simple and efficient. 只要保持足够的独立性,您就可以在这里知道代码简单有效。


Of course...this can be simplified. 当然...这可以简化。 The last if statement can be changed to a return : 最后一个if语句可以更改为return

 if (a) return true; return false; 

converts to: 转换为:

 return a; 
include = (function () {
    //set up some simple names for concepts:
    var directory = options.directory;
    var isDot = file === '.';
    var all = options.all;
    var almost = options.almostall;

    if (directory && !isDot)
        return false;

    if (!dotted)
        return true;

    if (all)
        return true;

    if (implied && almost)
        return true;

    return directory && isDot;
}());

which of course can be simplified by converting the last if to a return again: 当然可以通过将最后一个if再次转换为return值来简化:

 if (a) return true; return b; 

converts to: 转换为:

 return a || b; 
include = (function () {
    //set up some simple names for concepts:
    var directory = options.directory;
    var isDot = file === '.';
    var all = options.all;
    var almost = options.almostall;

    if (directory && !isDot)
        return false;

    if (!dotted)
        return true;

    if (all)
        return true;

    return (implied && almost) ||
        (directory && isDot);
}());

...and again: ...然后再次:

include = (function () {
    //set up some simple names for concepts:
    var directory = options.directory;
    var isDot = file === '.';
    var all = options.all;
    var almost = options.almostall;

    if (directory && !isDot)
        return false;

    if (!dotted)
        return true;

    return (all) ||
        (implied && almost) ||
        (directory && isDot);
}());

...and again: ...然后再次:

include = (function () {
    //set up some simple names for concepts:
    var directory = options.directory;
    var isDot = file === '.';
    var all = options.all;
    var almost = options.almostall;

    if (directory && !isDot)
        return false;

    return (!dotted) ||
        (all) ||
        (implied && almost) ||
        (directory && isDot);
}());

...and again: ...然后再次:

 if (a) return false; return b; 

converts to: 转换为:

 return !a && b; 
include = (function () {
    //set up some simple names for concepts:
    var directory = options.directory;
    var isDot = file === '.';
    var all = options.all;
    var almost = options.almostall;

    return !(directory && !isDot) && (
        (!dotted) ||
        (all) ||
        (implied && almost) ||
        (directory && isDot)
    );
}());

This can be simplified further by using De Morgan's laws : 可以使用De Morgan定律进一步简化:

 !(a && b) 

converts to: 转换为:

 !a || !b 
include = (function () {
    //set up some simple names for concepts:
    var directory = options.directory;
    var isDot = file === '.';
    var all = options.all;
    var almost = options.almostall;

    return (!directory || isDot) && (
        (!dotted) ||
        (all) ||
        (implied && almost) ||
        (directory && isDot)
    );
}());

And there you have it, about as simple as the logic can get. 一切就在这里,就像逻辑可以得到的一样简单。 You could, of course, choose to expand the variables back to their original definition, but I would encourage you not to. 当然,您可以选择将变量扩展回其原始定义,但我鼓励您不要这样做。 I would actually encourage you not to simplify beyond the simple chain of if..return statements. 实际上,我鼓励您不要简化if..return语句的简单if..return

If you make the code terser it's more challenging to read and understand which makes it more challenging to debug. 如果使代码变得更复杂,则阅读和理解将更具挑战性,这将使调试更具挑战性。 It's quite likely that I've made a mistake somewhere in this post while "simplifying" the code, and it's not immediately obvious when reading the series of && and || 在“简化”代码时,我很可能在本文的某个地方犯了一个错误,并且在阅读&&||系列时并不太明显。 operators if mistakes were made. 操作员是否犯了错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM