use string "includes()" in switch Javascript case - javascript

In Javascript, is there a way to achieve something similar to this ?
const databaseObjectID = "someId"; // like "product/217637"
switch(databaseObjectID) {
case includes('product'): actionOnProduct(databaseObjectID); break;
case includes('user'): actionOnUser(databaseObjectID); break;
// .. a long list of different object types
}
This is more a curiosity question to understand the possibilities of switch / case, as in this particular case I have solved my problem using const type = databaseObjectID.split('/')[0]; and apply the switch case on type

This will work, but it shouldn't be used in practice.
const databaseObjectID = "someId"; // like "product/217637"
switch(true) {
case databaseObjectID.includes('product'): actionOnProduct(databaseObjectID); break;
case databaseObjectID.includes('user'): actionOnUser(databaseObjectID); break;
// .. a long list of different object types
}

You usage would be considered an abuse of case.
Instead just use ifs
if (databaseObjectId.includes('product')) actionOnProduct(databaseObjectID);
else if (databaseObjectId.includes('user')) actionOnUser(databaseObjectID);
// .. a long list of different object types
If the ObjectId contains static content around the product or user, you can remove it and use the user or product as a key:
var actions = {
"product":actionOnProduct,
"user" :actionOnUser
}
actions[databaseObjectId.replace(/..../,"")](databaseObjectId);

Sorry, I'm a noob so someone will probably have to clean this up, but here is the idea. Pass to a function to check and return a category then use the switch.
function classify(string){
var category = categorize(string);
switch (category) {
case 'product':
console.log('this is a product');
break;
case 'user':
console.log('this is a user');
break;
default:
console.log('category undefined');
}
}
function categorize(string){
if (string.includes('product')){
return 'product';
}
if (string.includes('user')){
return 'user';
}
}
classify("product789");
classify("user123");
classify("test567");
Sorry, as well, for not matching your example.

Question:
use string “includes()” in switch Javascript case
While the includes() method will work, it is case sensitive, and just matches any characters. I have found a Regex solution that I like much better, and provides a lot of flexibility. For example, you could easily change this to match only WORDS.
var sourceStr = 'Some Text and literaltextforcase2 and more text'
switch (true) { // sourceStr
case (/LiteralTextForCase1/i.test(sourceStr)):
console.log('Case 1');
break;
case (/LiteralTextForCase2/i.test(sourceStr)):
console.log('Case 2');
break;
default:
console.log('ERROR No Case provided for: ' + sourceStr);
};
//-->Case 2

Related

How to change the switch statement below to polymorphism in javascript and also how to access the different classes

let type = document.querySelector('#productType');
type.addEventListener('change', function() {
switch (type.value) {
case 'DVD':
document.querySelector('.DVD').classList.add('visible');
document.querySelector('.Furniture').classList.remove('visible');
document.querySelector('.Book').classList.remove('visible');
break;
case 'Furniture':
document.querySelector('.Furniture').classList.add('visible');
document.querySelector('.DVD').classList.remove('visible');
document.querySelector('.Book').classList.remove('visible');
break;
case 'Book':
document.querySelector('.Book').classList.add('visible');
document.querySelector('.Furniture').classList.remove('visible');
document.querySelector('.DVD').classList.remove('visible');
break;
}
})
You could take an array of ids and update the wanted value with a single loop
ids = ['DVD', 'Furniture', 'Book'];
// update
ids.forEach(id => document.querySelector(id).classList[id === value
? 'add'
: 'remove'
]('visible'));

prevent app from creating windows system folders using regex?

I'm building a browser-based app which allows users to create folders with some .json files (not big deal). The thing is, the framework that I'm using (NW.js) doesn't appears to care about allowing users to create folders named "CON" or "NUL"; These are not supposed to be created, the files inside just vanish and it's somewhat difficult to delete the folder themselves.
I can no problem make something like this to prevent to happen:
var newFolder = "nul";
function checkFolderName(text) {
switch(newFolder) {
case "con":
console.log("folder can't be created")
break;
case "nul":
console.log("folder can't be created")
break;
// and so on... there's about 23 windows-reserved names that I could find
default:
console.log("folder can be created")
}}
checkFolderName(newFolder);
But I wonder if there is some easier way to check this through Regex/Javascript, or maybe some different approach to this idea.
Here's a little cleaner way to write what you want.
Function renamed to imply that it takes a string and returns a boolean.
If the input string is invalid, returns false.
All banned names are grouped together in an easily updated list.
Validity is checked by if the list contains the name.
function folderNameIsValid (name) {
let valid = false;
if (!name || typeof(name) !== 'string') {
return valid;
}
const bannedNames = [
'con',
'nul'
];
if (!bannedNames.includes(name.toLowerCase())) {
valid = true;
}
return valid;
}
if (folderNameIsValid('NUL')) {
console.log('folder can be created');
} else {
console.log('folder cannot be created');
}
My friend could help me to do this with regex:
let valid = /^(con|prn|aux|nul|com|lpt)\d*$/gi.test(newFolder)
console.log(valid) // true or false
However, it's starts to get pretty clanky if you want to add more "banned names", so jaredcheeda's suggestion it's pretty handy in this case
If you want to use regex you can do it like this:
if (/^con|nul|abc|xyz$/.test(newFolder))
console.log("folder can't be created");
The | character means 'or'. so the test function will return true if newFolder is "con" or "nul" or "abc" or "xyz"
The ^ and the $ sign are the beginning and the ending of the string.
If you want to know exactly what was the illegal part, you can use this:
var matching = newFolder.match(/^con|nul|abc|xyz$/);
if (matching) {
console.log("folder can't be created, found " + matching[0]);
}
You can also use this notation of switch case:
switch (newFolder)
{
case "con":
case "nul":
case "abc":
case "xyz":
console.log("folder can't be created");
break;
default:
console.log("folder can be created");
}

Loop through Switch statement in apps script

I have an object with key value pairs made of questions and answers. There are several different ways to ask the question, so I'm trying to group questions that mean the same using a switch statement and the js match function.
{ 'Name?' : 'bob', q2: a2, .......}
I want to loop through the objects and find partial matches between the array elements and the object keys. So far I have:
switch (/terms/.test(key)) {
case ( terms ="Name|What's Your Name?"):
text = "matched";
break;
default:
text = "default";
Logger.log(key);
}
Logger.log(text)
});
The output in part shows:
18-10-09 15:37:41:415 EDT] *What's Your Name?*
[18-10-09 15:37:41:416 EDT] default
Obviously a match is not occurring. How can I get this working?
EDIT:
I changed my code to:
Object.keys(obj).forEach(function(key) {
switch (true) {
case (/^Name|term2$/.test(key)):
text = "MATCHED!!!!";
break;
case 0:
case 6:
// text = "It is Weekend";
break;
default:
text = "default";
Logger.log(key);
}
Logger.log(text)
});
Still no match.
You can combine switch cases like this:
switch (key) {
case 'Name':
case 'What\'s Your Name?':
// Do something
break;
default:
// Do something
}
This code is equivalent to:
if (key === 'Name' || key === 'What\'s Your Name?') {
// Do something
} else {
// Do something
}

When using a switch statement in Javascript with multiple cases, how can I refer to a case?

So I have some code:
var Animal = 'Giraffe';
switch (Animal) {
case 'Cow':
case 'Giraffe':
case 'Dog':
case 'Pig':
console.log('This animal will go on Noah\'s Ark.');
break;
case 'Dinosaur':
default:
console.log('This animal will not.');
}
Ideally, I'd like the first console.log to print "This Giraffe will go on Noah's Ark", or whatever the variable Animal happened to be. I want to refer to the case. However, I'm not sure how to write that code. Can someone help?
Just use additional arguments to log and Animal.
console.log('This', Animal, 'will go on Noah\'s Ark.');
You could use a token %s (string in this case) and than after a comma use your variable:
var Animal = 'Giraffe';
switch (Animal) {
case 'Cow':
case 'Giraffe':
case 'Dog':
case 'Pig':
console.log('This %s will go on Noah\'s Ark.', Animal);
break;
case 'Dinosaur':
default:
console.log('%s will not.', Animal);
}
Just use your variable:
var Animal = 'Giraffe';
switch (Animal) {
case 'Cow':
case 'Giraffe':
case 'Dog':
case 'Pig':
console.log('This ' + Animal + ' will go on Noah\'s Ark.');
break;
case 'Dinosaur':
default:
console.log('This animal will not.');
}
(note: I'm using string concatenation here under the assumption that you may actually want to do something other than use the console.log function to do something like this - if you really just want to use console.log, it may be more reasonable to use one of the other answers provided)

Replace switch with a better pattern (Javascript)

I have to upgrade my app to display pages based on a users type and role properties. Currently I employ a simple switch statement to do this based on user type, e.g.
switch(type) {
case 'a':
return CONSTANT.ONE;
case 'b':
return CONSTANT.TWO;
default:
return null;
}
The switch just returns a constant string which dictates the view showm, but that isn't scalable as number of types , roles increases. Can anyone suggest a good pattern to use in this case. I thought a state pattern might be good but is that over the top just to return a string ?
Thanks
Very similarly to #MarkusJarderot, but with a few important differences in behavior, I would use:
var mapping = {
'a': CONSTANT.ONE,
'b': CONSTANT.TWO,
'_default': null
};
return mapping.hasOwnProperty(type) ? mapping[type] : mapping["_default"];
When the value of mapping[type] is falsy, this will still return it, rather than going to the null alternative. That will be very helpful when one of your values is 0 or an empty string.
Use an object as a lookup:
var roles = {};
Then you can add roles like this:
roles['a']=CONSTANT.ONE;
and look them up like this:
var xxx = roles['a'];
This way you can add things to the roles in different places in your code
You can use Strategy Pattern:
//Example without strategy pattern
gameDifficulty(difficulty) {
switch(difficulty){
case 'easy':
easyGameMode();
break;
case 'difficult'
difficultMode();
break;
}
}
// Using Strategy
const strategies = {
easy: easyGameMode(),
difficult: difficultGameMode(),
//More strategies
__default__: normalGameMode()
}
const easyGameMode = (game) => {
game.difficulty(1);
//Do easy game mode stuff in here
return game;
}
const normalGameMode= (game) => {
game.difficulty(2);
//Do normal game mode stuff in here
return game;
}
const difficultGameMode = (game) => {
game.difficulty(3);
//Do difficult game mode stuff in here
return game;
}
const startGame = (game, difficulty) => {
const gameModifier = strategies[difficulty] ?? strategies.__default__;
return gameModifier(game, difficulty);
}
More info in this article.

Categories