简体   繁体   English

使用if / else vs.switch

[英]Using if/else vs. switch

I'm wondering if it would be better to use a switch statement in my specific case. 我想知道在我的特定情况下使用switch语句是否会更好。

I'm writing an Alexa Custom Skill, and I need to "redirect" to the appropriate intent depending on the available information (aka slots). 我正在写Alexa自定义技能,我需要根据可用信息(也称为广告位)“重定向”到适当的意图。 Below is what I have currently (using if/else ): 以下是我目前使用的(使用if/else ):

if (_type === "IntentRequest") {

    this.handler.state = states.START;
    if (_slots.indexOf("address") != -1) {
        this.emitWithState("GoingToAddressIntent");
    } else if (_slots.indexOf("place") != -1) {
        this.emitWithState("GoingToPlaceIntent");
    } else if (_slots.indexOf("type") != -1) {
        this.emitWithState("GoingToTypeIntent");
    } else if (_slots.indexOf("purpose") != -1) {
        this.emitWithState("GoingToPurposeIntent");
    } else {
        this.emit("Unhandled");
    }

}

I expect _slots to be an array of any permutations of the four elements, [ "address", "place", "type", "purpose" ] . 我希望_slots[ "address", "place", "type", "purpose" ]这四个元素的任何排列的数组。 Therefore, it could be anything from [ "address" ] to [ "place", "purpose" ] to etc. etc., but always in the same order (eg [ "purpose", "address" ] would never happen). 因此,它可以是从[ "address" ][ "place", "purpose" ]等的任何东西,但是总是以相同的顺序进行 (例如[ "purpose", "address" ]永远不会发生[ "purpose", "address" ] )。

The order of the comparisons matters because there is a "hierarchy" of information; 比较的顺序很重要,因为存在信息的“层次结构”。 so if the "address" slot is present, I have to emit the "GoingToAddressIntent" regardless of what other slots are available. 因此,如果存在“地址”插槽,则无论是否有其他可用插槽,我都必须emit "GoingToAddressIntent" Given this requirement, I thought using a switch statement maybe more straightforward and readable despite having to have a few extra lines of code to "convert" the array of strings to an array of booleans. 考虑到这一要求,我认为使用switch语句可能更直接易读,尽管必须有一些额外的代码行才能将字符串数组“转换”为布尔数组。 It clearly lays out the hierarchy & make sure they are evaluated in order. 它清楚地列出了层次结构并确保按顺序评估它们。 I could do: 我可以做:

if (_type === "IntentRequest") {

    this.handler.state = states.START;
    slots = [ 
        _slots.indexOf("address") != -1,
        _slots.indexOf("place") != -1,
        _slots.indexOf("type") != -1,
        _slots.indexOf("purpose") != -1
    ]

    switch(slots.indexOf(true)) {
    case 0:
        this.emitWithState("GoingToAddressIntent");
        break;
    case 1:
        this.emitWithState("GoingToAddressIntent");
        break;
    case 2:
        this.emitWithState("GoingToTypeIntent");
        break;
    case 3:
        this.emitWithState("GoingToPurposeIntent");
        break;
    default:
        this.emit("Unhandled");
    }

}

... in which case I have an extra line to define the array of booleans, use indexOf() to get the index of the first occurrence of a true literal (because all 4 slots are always in the order of hierarchy), and run it through the switch statement. ...在这种情况下,我有一行额外的代码来定义布尔数组,使用indexOf()获取第一次出现的true文字的索引(因为所有4个插槽始终按层次结构排列),然后运行它通过switch语句。 However I wanted ask experts on their ideas of what best programming practice is in this case and the reasoning behind it because I want this to become a long-term project that is maintainable, and also I believe I can learn something from their insights. 但是,我想请专家们就这种情况下的最佳编程实践及其背后的原因提出意见,因为我希望这成为一个可维护的长期项目,而且我相信我可以从他们的见解中学习到一些东西。


Please leave a comment if you think this should be migrated to another community on SE, but from my research (although 3 years old) I believe this should be fine (I'm just not 100% confident on this). 如果您认为应该将其迁移到SE上的另一个社区,请发表评论,但是根据我的研究 (尽管3岁),我认为应该没问题(我对此不是100%的自信)。

If they're always in the order of precedence in _slots , maybe you could make a hash map to the state you're going to emit... 如果它们始终以_slots的优先顺序_slots ,也许您可​​以对要发出的状态进行哈希映射...

const map = {
  address: "GoingToAddressIntent",
  place: "GoingToPlaceIntent",
  type: "GoingToTypeIntent",
  purpose: "GoingToPurposeIntent"
};

const state = map[_slots[0]];
if (state) {
  this.emitWithState(state);
} else {
  this.emit("Unhandled");
}

I wouldn't go with your example of the switch statement. 我不会接受您的switch语句示例。 People could understand what you're attempting to do, but it does seem pretty convoluted. 人们可以理解您要尝试执行的操作,但是看起来确实很复杂。 I use switch statements pretty liberally, mostly in backend code, and I think it could work fine here. 我相当自由地使用switch语句,主要是在后端代码中使用,我认为它在这里可以很好地工作。 A group of if/else is fine too, since there's only 4 cases you need to work through. 一组if / else也可以,因为您只需要处理4种情况。 Lets roll with the switch statement since that's what you're asking about. 让我们一起来看看switch语句,因为这就是您要问的问题。

Based on your explanation, the order is always going to be the same, although the first value you get may be different. 根据您的解释,尽管您获得的第一个值可能不同,但是顺序始终是相同的。 So the solution would be to simply grab the first value, and switch over that. 因此,解决方案将是简单地获取第一个值,然后进行切换。

if (!!slots.length) {
  var keyword = slots[0];
  switch (keyword) {
    case 'address':
        this.emitWithState("GoingToAddressIntent");
        break;
    case 'place':
        this.emitWithState("GoingToPlaceIntent");
        break;
    case 'type':
        this.emitWithState("GoingToTypeIntent");
        break;
    case 'purpose':
        this.emitWithState("GoingToPurposeIntent");
        break;
    default:
        this.emit('Unhandled'); // I typically throw an exception here
  }
}

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

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