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

dth*_*ree 1 javascript boolean ternary-operator

在 linting 我的 Javascript 时,我遇到了一个no-unneeded-ternary关于我的复杂三元选项的警告。

我知道如何在简单的布尔表达式上解决这个问题:

var obvious = (1 === 1) ? true : false;
// can simply become:
var obvious = (1 === 1);
Run Code Online (Sandbox Code Playgroud)

但是,在我下面的布尔表达式中,我不知道如何正确缩小范围而不用担心破坏碰巧非常复杂的东西:

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

什么是正确的速记实现?


试一试:

const include = !(options.directory && file !== '.') || 
  (!dotted) || 
  (dotted && options.all) ||
  (dotted && !implied && options.almostall) ||
  (options.directory && file === '.');
Run Code Online (Sandbox Code Playgroud)

这样对吗?

zzz*_*Bov 5

当您使用一堆链接的三元运算符编写代码时,它会变得更简洁,通常可读性更低。

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

为了分解它,我将首先使用模块模式扩展它:

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;
}());
Run Code Online (Sandbox Code Playgroud)

这可以简化。检查后!dotted,dotted必须为真,并变得多余:

true && a
Run Code Online (Sandbox Code Playgroud)

转换为:

a
Run Code Online (Sandbox Code Playgroud)
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;
}());
Run Code Online (Sandbox Code Playgroud)

作为一个足够好的问题,你可以随意停在这里,知道代码简单有效。


当然……这可以简化。最后一条if语句可以更改为return

if (a)
    return true;
return false;
Run Code Online (Sandbox Code Playgroud)

转换为:

return a;
Run Code Online (Sandbox Code Playgroud)
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;
}());
Run Code Online (Sandbox Code Playgroud)

当然可以通过将最后if一个return再次转换为 a来简化:

if (a)
    return true;
return b;
Run Code Online (Sandbox Code Playgroud)

转换为:

return a || b;
Run Code Online (Sandbox Code Playgroud)
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);
}());
Run Code Online (Sandbox Code Playgroud)

...然后再次:

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);
}());
Run Code Online (Sandbox Code Playgroud)

...然后再次:

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);
}());
Run Code Online (Sandbox Code Playgroud)

...然后再次:

if (a)
    return false;
return b;
Run Code Online (Sandbox Code Playgroud)

转换为:

return !a && b;
Run Code Online (Sandbox Code Playgroud)
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)
    );
}());
Run Code Online (Sandbox Code Playgroud)

这可以通过使用德摩根定律进一步简化:

!(a && b)
Run Code Online (Sandbox Code Playgroud)

转换为:

!a || !b
Run Code Online (Sandbox Code Playgroud)
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)
    );
}());
Run Code Online (Sandbox Code Playgroud)

你有它,就像逻辑可以得到的一样简单。当然,您可以选择将变量扩展回其原始定义,但我建议您不要这样做。我实际上鼓励您不要在简单的if..return陈述链之外进行简化。

如果您使代码更简洁,那么阅读和理解就会更具挑战性,这使得调试更具挑战性。我很可能在“简化”代码时在这篇文章的某个地方犯了一个错误,如果犯了错误,在阅读&&and||运算符系列时并不是很明显。