Alternative to the "switch" Statement

Viewed 12660

I do not want to use Switch in my code, so I'm looking for some alternative

Example with Switch:

function write(what) {

  switch(what) {

    case 'Blue':
      alert ('Blue');
    break;

    ...

    case 'Red':
      alert ('Red');
    break;

  }

}

Example without Switch:

colors = [];

colors['Blue'] = function() { alert('Blue'); };
colors['Red'] = function() { alert('Red'); };


function write(what) {

  colors[what]();

}

My questions are:

  1. Do you know any other alternatives?
  2. Is this best solution?
9 Answers

I have only a note about your second approach, you shouldn't use an Array to store non-numeric indexes (that you would call in other languages an associative array).

You should use a simple Object.

Also, you might want to check if the what argument passed to your write function exists as a property of your colors object and see if it's a function, so you can invoke it without having run-time errors:

var colors = {};

colors['Blue'] = function() { alert('Blue'); };
colors['Red'] = function() { alert('Red'); };


function write(what) {
  if (typeof colors[what] == 'function') {
    colors[what]();
    return;
  }
  // not a function, default case
  // ...
}

You could use object literals, and try catch to trap the default:

function write(what) {
    var colors = {
    'Blue': function(){ alert('Light-Blue'); },
    'Red': function(){ alert('Deep-Red'); },
    'Green': function(){ alert('Deep-Green'); }
    }
    try {colors[what]();}
    catch(err) {colors['Green']();}//default behaviour
}
write('Pink');

Question 2:

Generally, if you can replace custom control structures with a dictionary lookup, you're perfectly fine. It's easy to read and highly elegant -- stick with it.

You are pretty much there already. If possible you might want to add a helper function to make the setup easier. For Example:

function setup(what)
{
    colors[what] = function() { alert(what); };
}

EDIT:
If what you want to do for each option is more complicated clearly this will not work. As mentioned in the comments by @roe this uses the global colors which is often frowned upon.

Alternatively, you can also use Dictionaries, so you could see the type of the function return, I think it's clean and scalable, although it's just pure JS.

const ColorDictionary = {
  red: 'applies red color',
  blue: ' applies blue color',
  green: 'applies green color',
}

const useShowColors = (color) => {

 // color will be selected or fallout to default value.
 const getColor = () => (
  ColorDicionary[color] ?? 'applies default color' 
 )
 
 return { getColor }
}

const { getColor } = useShowColors() //pass the color you wish.

An alternative is to define a class with a write method, and override that in subclasses Red and Blue to do the right thing.

Whether or not that is better than your proposed solution, depends on your particular situation.

As I said, it's great. The only thing I can add to your solution is that it's perhaps better to localize your colors.

function write(what) {
    var colors = [];
    colors['Blue'] = function() { alert('Blue'); };
    colors['Red'] = function() { alert('Red'); };
    colors[what]();
}
Related