简化if/else语句?

Reb*_*van 31 javascript conditional if-statement

我正在尝试简化以下内容:

function handleDirection(src) {
  if (src === 'left') {
    if (inverse) {
      tracker--;
    } else {
      tracker++;
    }
  } else {
    if (inverse) {
      tracker++;
    } else {
      tracker--;
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

减少条件数量.该src要么是'left''right'始终.

Nin*_*olz 52

您可以查看第一次检查的结果.

这是一项独家OR检查.

// typeof inverse === 'boolean'

function handleDirection(src) {
    if (src === 'left' === inverse) {
        tracker--;
    } else {
        tracker++;
    }
}
Run Code Online (Sandbox Code Playgroud)

检查按以下顺序评估表达式(src === 'left') === inverse:

src === 'left' === inverse
---- first ---             returns a boolean value
--------- second --------- take result of former check & compairs it with another boolean
Run Code Online (Sandbox Code Playgroud)

  • 我绝对同意@marcelm.尽管这个答案看起来很精彩,但并不是很明显发生了什么. (7认同)
  • 只有当你真的需要提升性能和/或只与那些能够直观地阅读并提出这一点的人合作时,我才会使用它.另一种方法可能更长,但对普通开发人员来说更具可读性. (5认同)
  • ^^仅在这种特殊情况下 (2认同)

Ala*_*ays 18

function handleDirection(src) {
   var movement = 1;
   if(src === 'left')
     movement = -1;

   if(inverse)
     tracker += movement;
   else
     tracker -= movement;
}
Run Code Online (Sandbox Code Playgroud)

  • @MagicLegend实际上,我认为变量有助于为解决方案带来"真实世界"的平价.其他答案集中于"效率",这在一个简单的案例中可能无关紧要.口译员不需要帮助阅读,但人类会这样做.虽然我投了赞成票,但我会更进一步,给变量一个更有意义的名字,比如`adjust`或`movement`. (3认同)
  • 这会创建一个不必要的额外变量imo ...在这种情况下,使用`tracker --`和`tracker ++`是增加和减少变量的正确方法.如果希望增加或减少变量多于一个,这可能是一个很好的指导方针. (2认同)

小智 11

你甚至可以只使用一行代码来完成它:

function getDirectionOffset(src) {
  tracker += (src === 'left' ? 1 : -1) * (inverse ? -1 : 1);
}
Run Code Online (Sandbox Code Playgroud)


Ror*_*san 7

这可以简化为返回1-1取决于状态的三元表达式.然后你可以把它添加到tracker.

function handleDirection(src) {
  var delta = (src === 'left' && inverse) || (src !== 'left' && !inverse) ? -1 : 1;
  tracker += delta;
}
Run Code Online (Sandbox Code Playgroud)

然后可以使用@NinaScholz在她的回答中指出的逻辑进一步简化:

function handleDirection(src) {
  var delta = (src === 'left') === inverse ? -1 : 1;
  tracker += delta;
}
Run Code Online (Sandbox Code Playgroud)


VLA*_*LAZ 5

假设inverse是一个标志你设置了一次,那么你不需要每次都考虑它,你可以计算一次它的影响并按原样使用它,这将减少你的代码分支和逻辑。如果您想在进行过程中更改它,那么您可能需要分离计算逻辑,以便重新使用它。

然后你也可以提取的运动方向成一个独立的功能,你handleDirection就变得非常简单-你计算的方向,你要根据去srcinvert

let tracker = 0;

//extract logic for the movement offset based on direction
function getDirectionOffset(src) {
  return src === 'left' ? 1 : -1;
}

//have a setter for the invert property
function setInverse(isInverse) {
  movementModifier = isInverse ? -1 : 1
}

//declare the variable dependent on the inverse property
let movementModifier;

//initialise movementModifier variable
setInverse(false);

function handleDirection(src) {
  const offset = getDirectionOffset(src) * movementModifier;
  
  tracker += offset;
}


// usage
setInverse(true);

handleDirection("left");
handleDirection("left");
handleDirection("right");

console.log(tracker);
Run Code Online (Sandbox Code Playgroud)

话虽如此,所有这些都表明您不应该使用一个函数,或者您应该以不同的方式使用它。您可以在一个类中收集所有这些功能,或者将所有信息传递给函数,因此您没有全局变量。这是该概念的面向对象实现示例:

class TrackerMover {
  constructor(inverse) {
    this.tracker = 0;
    this.movementModifier = inverse ? 1 : -1
  }
  
  handleDirection(src) {
   const offset = this.getDirectionOffset(src) * this.movementModifier;

    this.tracker += offset;
  }
  
  getDirectionOffset(src) {
    return src === 'left' ? -1 : 1;
  }
  
  getPosition() {
    return this.tracker;
  }
}


//usage
const mover = new TrackerMover(true);

mover.handleDirection("left");
mover.handleDirection("left");
mover.handleDirection("right");

console.log(mover.getPosition())
Run Code Online (Sandbox Code Playgroud)

顺便说一句,另一种选择是不要每次都计算运动。实际上,你知道发生了什么,每次-实际上,你有一个事实表,其中你输入的src === leftinverse与输出是你如何修改追踪。

+--------+------------+--------+
| isLeft | isInverted | Offset |
+--------+------------+--------+
| true   | true       |     -1 |
| true   | false      |      1 |
| false  | true       |      1 |
| false  | false      |     -1 |
+--------+------------+--------+
Run Code Online (Sandbox Code Playgroud)

所以,你可以把那张桌子放进去。

+--------+------------+--------+
| isLeft | isInverted | Offset |
+--------+------------+--------+
| true   | true       |     -1 |
| true   | false      |      1 |
| false  | true       |      1 |
| false  | false      |     -1 |
+--------+------------+--------+
Run Code Online (Sandbox Code Playgroud)

在这种情况下,这可能是一种矫枉过正,但如果有更多标志(包括更多标志)和/或结束状态,这种方法可能很有用。例如,也许您想引入四个方向,但tracker如果是up或则不要修改该值down

+-----------+------------+--------+
| direction | isInverted | Offset |
+-----------+------------+--------+
| left      | true       |     -1 |
| left      | false      |      1 |
| right     | true       |      1 |
| right     | false      |     -1 |
| up        | false      |      0 |
| up        | true       |      0 |
| down      | false      |      0 |
| down      | true       |      0 |
+-----------+------------+--------+
Run Code Online (Sandbox Code Playgroud)

如您所见,现在不仅仅是布尔值,您可以处理任何值。使用一张桌子,你也会invert变成类似 的东西windDirection,所以如果运动是left并且windDirectionright,结果就像现在的样子,但是你可以有方向left和风left,所以你移动得更远。或者你可以移动up和风向是left如此tracker(在这一点上的X坐标)将要实际进行修改。

+-----------+---------------+---------+
| direction | windDirection | OffsetX |
+-----------+---------------+---------+
| left      | right         |      -1 |
| left      | up            |       1 |
| left      | down          |       1 |
| left      | left          |       2 |
| right     | up            |      -1 |
| right     | down          |      -1 |
| right     | right         |      -2 |
| right     | left          |       1 |
| up        | up            |       0 |
| up        | down          |       0 |
| up        | left          |       1 |
| up        | right         |      -1 |
| down      | up            |       0 |
| down      | down          |       0 |
| down      | left          |       1 |
| down      | right         |      -1 |
+-----------+---------------+---------+
Run Code Online (Sandbox Code Playgroud)

考虑到四个方向和四个风向的逻辑对于以后的阅读和维护来说可能会很烦人,而如果您只有一个查找表,则很容易并且您可以轻松地将其扩展到甚至处理对角线(让我们假设他们通过0.5而不是1)更改值,只要您只是从表中获取值,您的算法就不会真正关心。