add a wildcard to a JavaScript switch statement - javascript

is there a way i can create a switch statement with a wildcard with the logic of:
case: '/jobs/'+WILDCARD and ending in +'-jobs' :
this is for the window.location.pathname, which could be '/jobs/design-jobs', or '/jobs/engineer-jobs' etc
but, there are other pages which start with '/jobs' I don't want this to apply to, e.g '/jobs/post'
or any suggestions on a better way?

No there are not wildcards for switch statements, but you could e.g. use RegExp and test against it:
if( path.match(/^\/jobs\/(.*)-jobs$/) !== null ) {
//jobs url
} else {
switch( path ) {
case '/jobs/post':
//something else
break;
}
}

One trick you can use in some cases could be to use a function to normalize the input of your switch, to turn variable inputs into the specific cases:
Instead of:
switch(input) {
case 'something': // something
case 'otherthing': // another
case '/jobs/'+WILDCARD: // special
}
You could do:
function transformInput (input) {
if (input.match(/jobs.*-jobs/) return 'JOBS';
return input;
}
switch(transformInput(input)) {
case 'something': // something
case 'otherthing': // another
case 'JOBS': // special
}

You can do something like this:
var categories = {
design: function(){ console.log('design'); },
engineer: function(){ console.log('engineer'); }
};
for(var category in categories)
if(window.location.pathname === '/jobs/' + category + '-jobs')
categories[category]();

Related

How can I combine these functions

I'm learning about JavaScript functions and I've written three, which are basically identical:
function filterAll() {
location.hash = "/"
}
function filterCompleted() {
location.hash = "/completed"
}
function filterActive() {
location.hash = "/active"
}
Rather than having three functions, is it possible to combine them and call the paramaters that I need at that time through one function name? This is how I see it in my head, but I can't seem to work it out:
function filters(all, completed, active) {
all = location.hash = "/";
completed = location.hash = "/completed";
active = location.hash = "/active";
}
filters(all);
Using an object literal as a simple map lookup you could do this->
const actions = {
all: '/',
completed: '/completed',
active: '/active'
}
function filter(action) {
location.hash = actions[action];
}
//use like
filter('all');
filter('completed');
filter('active');
If you don't want to pass a string, another idea is using the map as an enum, to do this we could do these changes->
function filter(action) {
location.hash = action;
}
//use like
filter(actions.all);
filter(actions.completed);
filter(actions.active);
You could use lots of consts like #Rounin mentions, but I'm not a fan of making more variables, even if they are scoped.
I'm not sure what you're trying to do, can you add some notes.
If it's to pass three variables then your last code sample is fine.
IF its to pass one variable that has three data points, then use an object.
var filters = {all:"/", completed: "/completed", active: "active"};
then you can retrieve the values with (for example) alert(filters.all);
You can try this:
function filters(val) {
switch (val) {
case 'all':
location.hash = "/";
break;
case 'completed ':
location.hash = "/completed";
break;
case 'active':
location.hash = "/active";
break;
default:
break;
}
}
You can combine the three functions below into a single function which takes a single parameter.
Step One
First, set up three const variables:
const all = '/';
const completed = '/completed';
const active = '/active';
Step Two
Next, declare your function:
function myFilter(filterType) {
location.hash = filterType;
}
Step Three
Now you can invoke one function using different values:
myFilter(all);
myFilter(completed);
myFilter(active);
It looks like this is what you are looking for.
function filters(filterType) {
if (filterType == 'all') location.hash = "/";
if (filterType == 'completed') location.hash = "/completed";
if (filterType == 'active') location.hash = "/active";
}
Although I would not recommend using your functions like this, this is how you would use the function:
filters('all'); // Set all filters
filters('completed'); // Set completed filters
filters('active'); // Set active filters
First You will need to define those variables as constant, just to used as parameters(action).
You may use that code Below
function filters ( action ) {
return action==="all" ? location.hash = "/" : action==="completed" ? location.hash = "/completed": action==="active" ? location.hash = "/active" : "No Match Found";
}
To test the function i provided a simple example:
let tod = "all";
let com = "completed";
let act = "active";
//Here you will see all the information you need. You can run it in your browser.
[filters(tod),filters(com),filters(act)].forEach;

Switch statement not behaving like it should

so i have a piece of code where i have an array (ar=[1,2,3,4,5]) and two functions. the functions are supposed to do the exact same thing: print out something if 1 exists in the array. but function func is always returning "nope" instead of "one" but function another always return the right thing. the only difference between the two functions is function func have a switch instead of an if/else. why? in the source code there are about 12 cases so i actually need to use the switch.
var ar=[1,2,3,4,5];
function func(num){
var one=num;
switch (one) {
case one===1:
console.log("one");
break;
default:
console.log("nope");
break;
}
}
function another (num) {
if(num===2){
console.log("found two");
} else if(num===3){
console.log("found thre");
} else{
console.log("nope");
}
}
ar.forEach(func);
ar.forEach(another);
You have to use the value you want to compare to one
hence
case 1:
instead of
case one===1
here's a fiddle
https://jsfiddle.net/cunx1ono/
Easiest way. Change the switch param to true if you want to use a comparison in the case, because one===1 returns true/false. This is why you always get "nope".
var ar=[1,2,3,4,5];
function func(num){
var one=num;
switch (true) {
case one===1:
console.log("one");
break;
default:
console.log("nope");
break;
}
}

Want to add new cases dynamically in switch statement using jquery [duplicate]

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.
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.
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>
You can use Object for switch cases. One of the advantages of using Object instead of Array for the case is that it drastically reduces errors caused by wrong indexes in Array. Using Object for cases, you can also extract your case values into another script. This helps for Single Responsibility Principle by concerning you only implementing business logic inside switch cases instead of worrying about maintaining the right case values.
const OP = {
ADD: 'ADD',
MULTIPLY: 'MULTIPLY',
};
const choice = 'ADD';
switch (choice) {
case OP.ADD:
console.log('You chose add');
break;
case OP.MULTIPLY:
console.log('You chose multiply');
break;
default:
console.log('Operation is not defined');
}

Switch Statement and jQuery hasClass function

I am trying to use a switch statement to check if the current page has a specific body class. This is kind of what I am looking for:
var bodyClass = $('body').hasClass('className')
switch(bodyClass) {
case 'homepage':
// console.log("This is the homepage");
break;
case 'residential-page':
// console.log("This is the residential page");
break;
default:
// console.log("default code block ran");
}
I do understand that the jQuery hasClass function returns true of false and is used like $('body').hasClass('someClassName') and this will return true or false. Also, my body typically has about 7-10 different class names for a given page.
This is not the use case for a switch in my opinion, but a simple set of branches
var body = $('body');
if(body.hasClass('abc')) {
}
else if(body.hasClass('def')) {
}
else {
/* default case */
}
/* etc */
I agree with the other answer that you're better suited to just use if, else if statements here, but an alternative would be to rip the classes off the body tag and check them against your strings:
var bodyClasses = ($('body').attr('class') || '').split(' ');
for (var i = 0, len = bodyClasses.length; i < len; i++) {
switch(bodyClasses[i]) {
case 'homepage':
// console.log("This is the homepage");
break;
case 'residential-page':
// console.log("This is the residential page");
break;
default:
// console.log("default code block ran");
}
}
I know this is an old thread, but it may help someone else.
If you are able to ensure the classes for the element are declared in a specific order, you could ensure the class you are checking for is first / last in the list, and use something similar to this:
var bodyClass = $('body').attr('class');
var firstClass = bodyClass.slice(0, bodyClass.indexOf(' '));
switch(firstClass) {
case 'homepage':
// Some code here
break;
case 'residential-page':
// Other code here
break;
default:
// More code here
}

JavaScript alternatives to handling switch cases that have properties

I have HTML elements defined like this
<div id="Jacob" validation="required alpha-numeric"></div>
<div id="Peter" validation="required minlen:4 maxlen:20"></div>
And in Javascript I was parsing and handling the validation="property1 property2 ... propertyN" like this:
// called from a foreach that uses split(' ')
validate(type) {
switch(type) {
case "required":
// ...
break;
case "alpha-numeric":
// ...
break;
}
}
I realise using a switch like this might be a bit verbose and archaic.
What would be an elegant way to parse parameters that have their own properties/values?
I don't know where you got the impression that switch statements are archaic. They're not.
As far as your particular case, you can use .split(":") to split the individual parts apart, and then match on that:
function validate(type) {
var parts = (type || "").split(":");
switch(parts[0].toLowerCase()) {
case "required":
// ...
break;
case "alpha-numeric":
// ...
break;
case "minlen":
// validate against parts[1]
break;
}
}
If you wanted to use a lookup rather than a switch, you can do that, but I'd say that's just a matter of preference:
var validators = {
"required": function (value) {
},
"alpha-numeric": function (value) {
},
"minlen": function (value, len) {
}
};
function validate (value, type) {
var parts = (type || "").split(":");
var validator = validators[parts[0].toLowerCase()];
if (validator) {
var result = validator(value, parts[1]);
}
}
One potential benefit of the second approach is that new validators can be added to the validator object at runtime, though if you wanted to make a pluggable system, you'd probably want to go with something more robust than just a plain object that can be arbitrarily modified.
you can create json of key function pair. And pick function using your type and call it.
var objOfFunction = {};
objOfFunction["required"] = requiredFunction;
objOfFunction["alpha-numeric"] = alphanFunction;
function validate(type) {
objOfFunction[type]();
}
function requiredFunction(){
alert("required");
}
function alphanFunction(){
alert("in alpha");
}
validate("required");
validate("alpha-numeric");

Categories

Resources