Running functions using switch statement performance in javascript - javascript

I have a code to generate math problems with random numbers. I am using switch statement to choose which task should be generated.
function genTask(taskid) {
switch (taskid) {
case 1:
// generate some numbers
return numbers;
break;
case 2:
// generate some numbers
return numbers;
break;
// ...
}
}
I think there may be some performance issues when I add 150+ cases. Does this code go trough every case? Wouldnt it be faster if there are separate functions for every task?
function task1() {
// generate some numbers
return numbers;
}
function task2() {
// ...
}
function genTask(taskid) {
switch (taskid) {
case 1:
return task1();
break;
case 2:
return task2();
break;
// ...
}
}
Is there a faster way to do this?

First of all, you need to know where you need to use if/else or switch/case.
When you need to check 2 to 3 conditions then you can use if/elseif/else
When you need to check 5 or above then definitely use switch/case
And based on speed switch/case is faster then if/else
Let's get back to the original point,
In your case, you have 2 choices
Write all code in one switch case.
Make functions in chunk and call-in switch case.
I suggest you go with the second choice because switch case also a faster way of execution compared to other conditional checks, But when you make different functions then you can easily modify it and debug it which more help in development, and performance not compromised in that case.

One more approach is you can use a object lookup
function task1() {
// generate some numbers
return numbers;
}
function task2() {
// some task
}
const taskMap = { 1: task1, 2: task2 };
function genTask(taskid, defaultVal) {
return (taskMap[taskid] && taskMap[taskid]()) || defaultVal;
}
This will be simple object lookup, though in terms of performance it might be slower than switch case but it increases resuability and readability of the code.

In general, I think the performance of "array" is better than "if/else" or "switch". See the reference below. In your specific case, if you comparing if/else to switch, then switch is better.
Using functions will not affect the performance ( I think ), but it is better and preferable as the code will be cleaner and readable.
Reference : https://www.oreilly.com/library/view/high-performance-javascript/9781449382308/ch04.html

Related

How can I print out all cases from a switch in node.js?

I have a simple program which uses a switch.
switch (value) {
case 'hello':
return ...
case 'hey':
return ...
case 'hi':
return ...
case 'howdy':
return ...
I am looking for a way to print all possible cases/variants of the const value in the switch. So that the value would equal the possible cases like "value=hello,hey,hi,howdy" and such. It sounds really simple yet I couldn't find any possible solution to work this out anywhere online.

js - is it possible to have two elements on the switch condition? [duplicate]

I'm trying to convert an if statement into a switch statement using javascript. This is the working if statement:
if(!error1(num, a_id) && !error2(num, b_id) && !error3(num, c_id) && !error4(num, d_id)) {
a.innerHTML = num;
Any tips on how to put this into a switch statement would be great. Thanks
You can make this a switch, but it's unclear why you would want to. On first glance, this isn't the kind of situation (selecting amongst a set of values and doing something different for each of them) that you use switch for.
Here's how, though I don't recommend it:
switch (false) {
case !error1(num, a_id):
case !error2(num, b_id):
case !error3(num, c_id):
case !error4(num, d_id):
// Do nothing
break;
default:
a.innerHTML = num;
break;
}
This works in JavaScript, but not in most other languages that have switch. The reason it works is that the case labels are evaluated when the execution point reaches them, and they're guaranteed to be evaluated in source code order. So you're switching on the value false, which will first be tested (using strict equality, ===) against the return value of !error1(num, a_id), and then if that doesn't match, against !error2(num, a_id), etc.; if none of them matches, then they all evaluated true, and the code in the default block runs.

javascript: avoding if else with javascript object when pattern matching is involved

I am basically trying to avoid branching. I will explain my doubt with the code:
My code is like:
name = "any_random_name_generated_dynamically"
//If else conditions
// foo and bar are the part of the name not the complete name
if (name.match('foo_pattern')) {
"do_thing_1"
}
else if (name.match('bar_pattern')) {
"do_thing_2"
}
else {
"do_thing_3"
}
Is there anyway I can avoid this using javascript objects? Or there any other way to do where less branching is involved.
I tried googling it bu didn't find anything for this particular issue.
You could create a resolve table:
var resolve=[
["Some pattern",function(){alert("wohoo");}],
...
["",function(){alert("default")}]
];
So now you can simply iterate through the table, and find the first pattern that matches, and execute its related function:
var name="somestring";
resolve.find(el=>name.match(el[0]))[1]();
Note that this will crash if no pattern is found, so take care to add a default one.
Alternatively you could use a switch (still ugly):
switch(true){
case name.match("sth") :
dosth();
break;
default:
dodefault();
break;
}

Is it bad to use a "not declared array"? Does the "not declared" array have a proper name in programming?

I was trying to use a if...else statement with arrays without having to declare the arrays. I got it to work this way:
if(['banana','apple','lemon'].indexOf(somevar) >-1)
{
//code
}
else if(['chicken','dog','elephant'].indexOf(somevar) >-1)
{
//code
}
.
.
.
And it keep going this way until some dozens of if...elses. The code is working fine, no problem noticed. Is it a bad pratice? Is it really an array? Can it cause some performance loss, memory leaks, or reference problems? Does the "not declared" array used in this code, if it is really an array, have a proper name in programming?
It seems pointless in my opinion, since you know exactly what element you want.
As for memory, the array should be deallocated as soon as you move to the next statement, and I would personally consider this bad practice in this instance, since, like I said earlier, it doesn't do anything since you know which will be selected.
If it's a static list that the user is going to select an element from, this is alright but I would probably define the array elsewhere and just reference that when needed, so you don't have to create the exact same array over and over again.
I consider it bad practice since if I wanted to add/remove/change an element in an array, I would rather just change the array when it's declared at the top, or change the data source. By sprinkling it through your code, you allow the possibility of hard to maintain code.
How about
switch(somevar) {
case 'banana': case 'apple': case 'lemon'
//...
break;
case 'chicken': case 'dog': case 'elephant'
//...
break;
}
You're just declaring/using arrays on-the-fly. Nothing really wrong with it, it's just one of many coding styles. e.g.
if (somevar == 'banana') || (somevar == 'apple') || etc...) {
...code...
} else if (somevar == 'chicken') || (somevar == 'dog') || etc...) {
... code
}
or perhaps
switch(somevar) {
case 'banana':// fall-through
case 'apple': // fall-through
case ...
.... code ...
break;
case 'chicken':
case 'dog':
etc...
}
They're all valid. It comes down to what your project's code style guidelines are and how many of these comparisons you need to do.
I see no problem, but I would declare these arrays for readability and maintenance:
var fruits = ['banana','apple','lemon'],
animals = ['chicken','dog','elephant'];
if(fruits.indexOf(somevar) > -1)
{
//code
}
else if(animals.indexOf(somevar) > -1)
{
//code
}
Now it's clearer why you check if someVar is in one array or the other, and it's easier to update the arrays - I want add another animal, I go to the animals array, not "the first else if block".
Yes, ['banana','apple','lemon'] is an array, but your code will fail when somevar === 'chicken' because ['banana','apple','lemon'].indexOf(somevar) === 0, which is a falsey value.
Also, your else if statement is redundant. You should check the indices by doing:
if(['banana','apple','lemon'].indexOf(somevar) >= 0 ) { ... }

Using an array through a switch() statement in Javascript

I'm trying to develop a simplified poker game through Javascript. I've listed all possible card combinations a given player might have in its hand ordered by its value, like this:
switch(sortedHand)
{
//Pair
case [1,1,4,3,2]: sortedHand.push(1,"Pair"); break;
case [1,1,5,3,2]: sortedHand.push(2,"Pair"); break;
case [1,1,5,4,2]: sortedHand.push(3,"Pair"); break;
case [1,1,5,4,3]: sortedHand.push(4,"Pair"); break;
case [1,1,6,3,2]: sortedHand.push(5,"Pair"); break;
case [1,1,6,4,2]: sortedHand.push(6,"Pair"); break;
case [1,1,6,4,3]: sortedHand.push(7,"Pair"); break;
case [1,1,6,5,2]: sortedHand.push(8,"Pair"); break;
case [1,1,6,5,3]: sortedHand.push(9,"Pair"); break;
case [1,1,6,5,4]: sortedHand.push(10,"Pair"); break;
Even though the "sortedHand" array stores values succesfully (as I've seen through console.log), the switch() statement always returns the default case, and everyone gets an straight flush. I fear this is a matter of the literal approach I've used to declare possible array values to be compared with the whole of "sortedHand", but I don't know any better. Is it even possible to use switch() in such a manner?
You can try switching on a textual representation of the array.
switch(sortedHand.join(' '))
{
//Pair
case '1 1 4 3 2': sortedHand.push(1,"Pair"); break;
case '1 1 5 3 2': sortedHand.push(2,"Pair"); break;
case '1 1 5 4 2': sortedHand.push(3,"Pair"); break;
case '1 1 5 4 3': sortedHand.push(4,"Pair"); break;
// etc.
}
As an alternative to specifying every case directly, perhaps build a function dispatch table using an object and get rid of the switch entirely.
var dispatch = {};
// Build the table however you'd like, for your application
for (var i = 0; i < 10; i++) {
(function(i) {
var hand = ...; // Add your hand logic here
dispatch[hand] = function() { sortedHand.push(i, "Pair"); };
})(i);
}
// Execute your routine
dispatch[sortedHand.join(' ')]();
the switch() statement always returns the default case
That's because the comparison doesn't check the array contents, but the array object itself. Objects are considered equal by their identity, so nothing will be equal to an object instantiated by a literal.
Is it even possible to use switch() in such a manner?
Yes, one can use objects in switch statements, but you would have to use references in the cases. Not applicable to your problem.
In your case, I'd suggest a stringification:
switch(sortedHand.join())
{
//Pair
case "1,1,4,3,2": sortedHand.push(1,"Pair"); break;
case "1,1,5,3,2": sortedHand.push(2,"Pair"); break;
case "1,1,5,4,2": sortedHand.push(3,"Pair"); break;
case "1,1,5,4,3": sortedHand.push(4,"Pair"); break;
case "1,1,6,3,2": sortedHand.push(5,"Pair"); break;
case "1,1,6,4,2": sortedHand.push(6,"Pair"); break;
case "1,1,6,4,3": sortedHand.push(7,"Pair"); break;
case "1,1,6,5,2": sortedHand.push(8,"Pair"); break;
case "1,1,6,5,3": sortedHand.push(9,"Pair"); break;
case "1,1,6,5,4": sortedHand.push(10,"Pair"); break;
but I guess there's an even better, arithmetic solution to detect the patterns you're after. That would be shorter and faster, but I'm not sure what exactly this snippet is supposed to do.
a faster, potentially reusable, and more flexible way of doing it is to use an object instead of case:
var ok= {
'1 1 4 3 2':1,
'1 1 5 3 2':2,
'1 1 5 4 2':3,
'1 1 5 4 3':4
}[ sortedHand.join(' ') ] ;
if(ok){ sortedHand.push( ok ,"Pair"); }
objects work great when one output is hinged on one input. if you need to do five things in each case, then you have to use case, but if you just need X to turn into Y, (a 1:1), Look Up Tables in the shape of Objects are ideal.
i imagine a RegExp can work here, i used them on a connect4 game to identify 4 in a row, but the above logic table should work as well or better than what you describe.
That will not quite work as you have it, but you can use sortedHand.join(',') and compare it with [1,1,1,2,5].join(',') which will compare the two arrays and should be true if their contents were the exact same (Be careful with numbers typed as strings!)
To be fair, though, I can't imagine why you would design your logic like that. Even a simple card game has hundreds of thousands of possible hands. You might do better using underscore.js's collection managing functions as it will be simpler, and just a better practice.
There are 1274 possible combinations of 5 cards in a regular deck. Listing them all out in a switch statement is completely ridiculous. Why not just have a function count any duplicates to check for 2,3,4-of-a-kinds and then check for straights? (Your array doesn't show suit so I'm assuming you are leaving it out).
But if you really want to do it that way, you could use a string. Strings work with switches, and you can even use them like arrays. e.g. "123"[0] == '1'. You can change them back and forth user functions like parseInt.
Since no one suggested this, use a for loop and count the number of cards with exactly the given value. Having such a function you can call 'cardCount = count(sortedHand, cardNumber)'. And of cause looping through all possible card-numbers will give you the hands.
Since a given player can only have 1x2, 2x2, 1x3, 1x3+1x2, 1x4 or straights/streets, you can return an array of all hits being arrays/objects stating the count and the cardNumber involved. So [{2, 5}, {3, 6}] for a full house.

Categories

Resources