jeudi 4 mai 2017

Using if/else vs. switch

I'm wondering if it would be better to use a switch statement in my specific case.

I'm writing an Alexa Custom Skill, and I need to "redirect" to the appropriate intent depending on the available information (aka slots). Below is what I have currently (using 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" ]. Therefore, it could be anything from [ "address" ] to [ "place", "purpose" ] to etc. etc., but always in the same order (e.g. [ "purpose", "address" ] would never happen).

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. 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. 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.hasOwnProperty("address"),
        _slots.hasOwnProperty("place")
        _slots.hasOwnProperty("type")
        _slots.hasOwnProperty("purpose")
    ]

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

Aucun commentaire:

Enregistrer un commentaire