1

Independent of which programming language, what options are there to shorten long switch statements with many similar cases?

From what I've searched, I found answers like this one but my cases are all different with only one integer changing like in a loop.

Regularly I use following switch statement construct in bash/PHP/Python/JavaScript and am looking for a shorter version:

switch ($device) {
    // 2ghz
    case "n2":
        return 1;
        break;
    case "nne2":
        return 2;
        break;
    case "ne2":
        return 3;
        break;
    case "ene2":
        return 4;
        break;
    case "e2":
        return 5;
        break;
    case "ese2":
        return 6;
        break;
    case "se2":
        return 7;
        break;
    case "sse2":
        return 8;
        break;
    case "s2":
        return 9;
        break;
    case "ssw2":
        return 10;
        break;
    case "sw2":
        return 11;
        break;
    case "wsw2":
        return 12;
        break;
    case "w2":
        return 13;
        break;
    case "wnw2":
        return 14;
        break;
    case "nw2":
        return 15;
        break;
    case "nnw2":
        return 16;
        break;

    // 5ghz
    case "n5":
        return 17;
        break;
    case "nne5":
        return 18;
        break;
    case "ne5":
        return 19;
        break;
    case "ene5":
        return 20;
        break;
    case "e5":
        return 21;
        break;
    case "ese5":
        return 22;
        break;
    case "se5":
        return 23;
        break;
    case "sse5":
        return 24;
        break;
    case "s5":
        return 25;
        break;
    case "ssw5":
        return 26;
        break;
    case "sw5":
        return 27;
        break;
    case "wsw5":
        return 28;
        break;
    case "w5":
        return 29;
        break;
    case "wnw5":
        return 30;
        break;
    case "nw5":
        return 31;
        break;
    case "nnw5":
        return 32;
        break;

    // 24ghz
    case "n24":
        return 33;
        break;
    case "nne24":
        return 34;
        break;
    case "ne24":
        return 35;
        break;
    case "ene24":
        return 36;
        break;
    case "e24":
        return 37;
        break;
    case "ese24":
        return 38;
        break;
    case "se24":
        return 39;
        break;
    case "sse24":
        return 40;
        break;
    case "s24":
        return 41;
        break;
    case "ssw24":
        return 42;
        break;
    case "sw24":
        return 43;
        break;
    case "wsw24":
        return 44;
        break;
    case "w24":
        return 45;
        break;
    case "wnw24":
        return 46;
        break;
    case "nw24":
        return 47;
        break;
    case "nnw24":
        return 48;
        break;

    default:
        return 0;
        break;
}
Community
  • 1
  • 1
Christoph Lösch
  • 645
  • 7
  • 22
  • 1
    if each switch case returns a value you can remove the `break` from each case – Professor Abronsius Nov 24 '16 at 12:15
  • 4
    If you're just returning a value then a dictionary or hashmap would suit better. A data type with keys and values where you provide a key and it returns the value to you. – SuperBiasedMan Nov 24 '16 at 12:16
  • 1
    Did you just say you use *switch* statements in *Python*? – Ébe Isaac Nov 24 '16 at 12:16
  • 1
    there is no need of switch in this case, it can easily done with arrays. – kamal pal Nov 24 '16 at 12:17
  • I think there is no best way to cover this situation in all languages. For example in python you prefer `if/else` statements over `switch` statements. So for Python I can think of a dictionary containing all cases as key and their return as value and looping over them with a simple for to check. – Shahin Nov 24 '16 at 12:25

9 Answers9

3

In Python you can use something as simple as this, if your return value is that simple:

items = ["n2","nne2","ne2","ene2", ...]
for idx, key in enumerate(items, start=1):
    if device == key:
        result = idx
    result = 0

Or in case you expect something more complicated in your return value:

my_dict = {
    "n2": 1,
    "nne2": 2,
    "ne2": 3,
    "ene2": 4,
    ...}

for key, value in my_dict.items():
    if device == key:
        result = value
    result = 0
Shahin
  • 1,415
  • 4
  • 22
  • 33
  • IMHO, this is the most complete answer so far. You can also directly search for the value in the `items` list (1st case), or try to retrieve it from `my_dict` with its key and use an exception if there is no such key (2nd case). So there is no real need to iterate explicitly, but your solution would work just as well; it shows what really happens and is easily translatable to other languages (which is good with OP's request). – Stefan Marinov Nov 24 '16 at 14:49
2

In JavaScript:

var cases = {
   "n2"   : 1,
   "nne2" : 2,
   "ne2"  : 3,
   "ene2" : 4,
   "e2"   : 5,
   "ese2" : 6,
   // and so on
};

var myCase = cases[$device] || 0;
Lukasz Wiktor
  • 19,644
  • 5
  • 69
  • 82
1

Try this with PHP

function yourFunction($devices) {
    $array = ["n2","nne2","ne2","ene2","e2","ese2","se2","sse2","s2","ssw2","sw2","wsw2"];

    if($key = array_search($devices, $array))
        return $key+1;

}
1

I suggest to use an indexed array with bash:

declare -A a=([n2]='1' [nne2]='2' [ne2]='3')
device="nne2"

return "${a[$device]}"   # returns with value 2
Cyrus
  • 84,225
  • 14
  • 89
  • 153
0

Use an array to store 'cases' as keys and return values as value. Then it will be possible to check if a given key exists in the array. If YES then return its value, if not then return default value.

malutki5200
  • 1,092
  • 7
  • 15
  • 1
    An example might be useful in order to change this from a **comment** into an answer – RiggsFolly Nov 24 '16 at 12:17
  • @RiggsFolly Normally I would agree with you but when the OP tags 4 completely different languages, a textual explanation of the steps to follow is good enough as far as I am concerned :-) – jeroen Nov 24 '16 at 12:24
  • Yes, I can't provide the answer because I don't know what language is he interested in ;-) – malutki5200 Nov 24 '16 at 12:26
  • @jeroen he said independent of which language, therefore a practical example of any language might be helpful – Masivuye Cokile Nov 24 '16 at 12:26
  • @MasivuyeCokile True, it would certainly make it better, but as it is, some steps to follow still has my preference over some *please try this* code. – jeroen Nov 24 '16 at 12:27
0

I don't know php so this is in python:

devices = ["n2", "nne2" ...] # populate it with your devices
...

def foo(device):
    if device in devices:
        return devices.index(device) + 1
    else:
        return 0
Yevhen Kuzmovych
  • 10,940
  • 7
  • 28
  • 48
0

If the number is ordered. There is no better way than to use array indexing.

On the other hand, if the values differ, the solution can be done with a simple implementation of a dictionary / HashMap / associative array.

In Python, you could use a dictionary as done below

keyList = ['n2','nne2',...] 
valueList = [1, 2, 3, ...]  # Must be same size as keyList
# Best to assign both the above lists 
# with files if there are 50+ entries

deviceDict = {}

for i in range(len(keyList)):
    deviceDict[keyList[i]] = valueList[i]
Ébe Isaac
  • 11,563
  • 17
  • 64
  • 97
0

If you need a solution independent of any specific programming language, you might try JSON (Javascript Object Notation).

Despite its name, JSON is a language-agnostic, text-based, data-interchange format, much like XML, CSV (or YAML).

Being language-independent, JSON may be interrogated and processed not only by Javascript, but also by Java, Python, PHP and many other languages.

Multiple languages can refer to and process the same JSON data.

A JSON example of the data in the question:

{
  "2ghz": {
    "n2": 1,
    "nne2": 2,
    "ne2": 3,
    "ene2": 4,
    "e2": 5,
    "ese2": 6,
    "se2": 7,
    "sse2": 8,
    "s2": 9,
    "ssw2": 10,
    "sw2": 11,
    "wsw2": 12,
    "w2": 13,
    "wnw2": 14,
    "nw2": 15,
    "nnw2": 16
  },

  "5ghz": {
    "n5": 17,
    "nne5": 18,
    "ne5": 19,
    "ene5": 20,
    "e5": 21,
    "ese5": 22,
    "se5": 23,
    "sse5": 24,
    "s5": 25,
    "ssw5": 26,
    "sw5": 27,
    "wsw5": 28,
    "w5": 29,
    "wnw5": 30,
    "nw5": 31,
    "nnw5": 32,
  },

  "24ghz": {
    "n24": 33,
    "nne24": 34,
    "ne24": 35,
    "ene24": 36,
    "e24": 37,
    "ese24": 38,
    "se24": 39,
    "sse24": 40,
    "s24": 41,
    "ssw24": 42,
    "sw24": 43,
    "wsw24": 44,
    "w24": 45,
    "wnw24": 46,
    "nw24": 47,
    "nnw24": 48
  }
}
Rounin
  • 27,134
  • 9
  • 83
  • 108
  • it does not have to be explicitely language-independent, i wanted to know what is the best way for every stated language. json might be a good idea but then again i would need something in bash which parses the json data.. – Christoph Lösch Nov 24 '16 at 23:43
0

Thank you very much for your contributions, I could come up with following examples. I hope they are the shortest possible variants for their language, if not, feel free to edit/correct.

Python dev2host.py:

#!/usr/bin/env python
def dev2host(device):
    devices = [
        "n2", "nne2", "ne2", "ene2", "e2", "ese2", "se2", "sse2", "s2", "ssw2", "sw2", "wsw2", "w2", "wnw2", "nw2", "nnw2", # 2ghz
        "n5", "nne5", "ne5", "ene5", "e5", "ese5", "se5", "sse5", "s5", "ssw5", "sw5", "wsw5", "w5", "wnw5", "nw5", "nnw5", # 5ghz
        "n24", "nne24", "ne24", "ene24", "e24", "ese24", "se24", "sse24", "s24", "ssw24", "sw24", "wsw24", "w24", "wnw24", "nw24", "nnw24", # 24ghz
    ]
    for host, key in enumerate(devices, start=1):
        if device == key:
            print host
        result = 0
    return;
dev2host("ne5")

PHP dev2host.php:

<?php
function dev2host($device) {
    $devices = [
        "n2", "nne2", "ne2", "ene2", "e2", "ese2", "se2", "sse2", "s2", "ssw2", "sw2", "wsw2", "w2", "wnw2", "nw2", "nnw2", // 2ghz
        "n5", "nne5", "ne5", "ene5", "e5", "ese5", "se5", "sse5", "s5", "ssw5", "sw5", "wsw5", "w5", "wnw5", "nw5", "nnw5", // 5ghz
        "n24", "nne24", "ne24", "ene24", "e24", "ese24", "se24", "sse24", "s24", "ssw24", "sw24", "wsw24", "w24", "wnw24", "nw24", "nnw24", // 24ghz
    ];
    if ($host = array_search($device, $devices)) {
        return $host+1;
    }
}
echo dev2host("ne5");
?>

Bash dev2host.sh:

#!/bin/bash
function dev2host() {
    declare -A devices=(
        [n2]='1' [nne2]='2' [ne2]='3' [ene2]='4' [e2]='5' [ese2]='6' [se2]='7' [sse2]='8' # 2ghz
        [s2]='9' [ssw2]='10' [sw2]='11' [wsw2]='12' [w2]='13' [wnw2]='14' [nw2]='15' [nnw2]='16' # 2ghz
        [n5]='17' [nne5]='18' [ne5]='19' [ene5]='20' [e5]='21' [ese5]='22' [se5]='23' [sse5]='24' # 5ghz
        [s5]='25' [ssw5]='26' [sw5]='27' [wsw5]='28' [w5]='29' [wnw5]='30' [nw5]='31' [nnw5]='32' # 5ghz
        [n24]='33' [nne24]='34' [ne24]='35' [ene24]='36' [e24]='37' [ese24]='38' [se24]='39' [sse24]='40' # 24ghz
        [s24]='41' [ssw24]='42' [sw24]='43' [wsw24]='44' [w24]='45' [wnw24]='46' [nw24]='47' [nnw24]='48' # 24ghz
    )
    echo "${devices[$1]}"
}
dev2host ne5

Javascript dev2host.js:

function dev2host($device) {
    var devices = {
        "n2":1, "nne2":2, "ne2":3, "ene2":4, "e2":5, "ese2":6, "se2":7, "sse2":8, // 2ghz
        "s2":9, "ssw2":10, "sw2":11, "wsw2":12, "w2":13, "wnw2":14, "nw2":15, "nnw2":16, // 2ghz
        "n5":17, "nnw5":18, "ne5":19, "ene5":20, "e5":21, "ese5":22, "se5":23, "sse5":24, // 5ghz
        "s5":25, "ssw5":26, "sw5":27, "wsw5":28, "w5":29, "wnw5":30, "nw5":31, "nnw5":32, // 5ghz
        "n24":33, "nnw34":34, "ne24":35, "ene24":36, "e24":37, "ese24":38, "se24":39, "sse24":40, // 24ghz
        "s24":41, "ssw24":42, "sw24":43, "wsw24":44, "w24":45, "wnw24":46, "nw24":47, "nnw24":48, // 24ghz
    };
    var host=devices[$device] || 0;
    return host;
}
document.write(dev2host("ne5"));
Christoph Lösch
  • 645
  • 7
  • 22