Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamically adding cases to a switch

I need to dynamically add cases to a switch. I want the user to be able to add items and every item needs it's own switch case.

like image 940
MystD Avatar asked Mar 03 '16 10:03

MystD


2 Answers

You can use object with callback functions instead:

// you can have initial casses
var callbacks = {
   'something': () => 42
};

// and you can create new entry with this function
function add(_case, fn) {
   callbacks[_case] = callbacks[_case] || [];
   callbacks[_case].push(fn);
}

// this function work like switch(value)
// to make the name shorter you can name it `cond` (like in scheme)
function pseudoSwitch(value) {
   if (callbacks[value]) {
      callbacks[value].forEach(function(fn) {
          fn();
      });
   }
}

and you can add new entry using:

add('something', function() {
   // case for something
});

NOTE:

You can also modify this to work a little bit different than the original switch because you can have a function that returns a value and use a switch-like expression (like in Scheme where everything is an expression that returns a value):

const value = cond(42);

Writing this type of pseudoSwitch/cond function is left as an exercise to the reader.

NOTE 2:

By default objects in JavaScript use strings as keys and if you need to use something that can't be easily converted to a string, like objects (that will be converted to [Object object]) then you can use Map object that accepts anything as keys. Note that symbols work differently and they are not converted to a string when used as key in array.

like image 76
jcubic Avatar answered Oct 04 '22 04:10

jcubic


This was the best/simpler solution for my needs:

const customSwitch = [
    {
        condition: 'case1',
        fn() { /* Do stuff if case1 */ },
    }, {
        condition: 'canBeChangedAnytime',
        fn() { /* Do stuff if case2 */ },
    },
    ...adSomeCasesDynamycallyHere,
]

// edit a condition:
customSwitch[0].condition = 'changed';

// use the switch
for (const { condition, fn } of customSwitch) {
    if (myValue === condition) {
        fn();
        break;
    }
}

customSwitch, may have the form of an object, which may improve readability. Eg: customSwitch = { myCond: { condition, fn }}

You can click the above snippet to see it working ;)

const customSwitch = [    {
    condition: 38,
    fn: val => $("body").append(val === 38 ? 'UP' : 'RIGHT') + ' ',
}, {
    condition: 40,
    fn: val => $("body").append((val === 40 ? 'DOWN' : 'LEFT')+ ' ') ,
}]

$('#option1').click(function () {
    customSwitch[0].condition = 38
    customSwitch[1].condition = 40
});

$('#option2').click(function () {
    customSwitch[0].condition = 39
    customSwitch[1].condition = 37
});


$(window).keydown(function (e) {
    for (const { condition, fn } of customSwitch) {
        if (e.keyCode === condition) {
            fn(e.keyCode);
            break;
        }
    }
});
.btn {
cursor:pointer;
padding:5px;
border-radius:5px;
background-color:#3C0;
margin-top:5px;
width:150px;
text-align:center;
display:inline-block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Press the four arrow keys:<br>
-if you click <b>option1</b> the switch will recognize UP and DOWN<br>
-if you click <b>option2</b> the switch will recognize LEFT and RIGHT<br>

<div id='option1' class='btn'>OPTION 1</div>
<div id='option2' class='btn'>OPTION 2</div>
<hr>
like image 21
TOPKAT Avatar answered Oct 04 '22 03:10

TOPKAT