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
}
Related
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'));
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");
}
I'm attempting to change a form input validator from handling errors 1 by 1, to handle errors all at once. Since there are a lot of moving parts, I'll try and isolate the key area of the component.
https://codepen.io/jodriscoll/pen/pXyMqa?editors=0010
129: while ( error < rules.length ) {
130: if ( !validations[rules[error]](vin_input.value) ) {
When there are rules (input requirements) defined, extract the input's value, then pass that value to validations's inner functions. If one of those functions within returns false, validation stops and the switch (error output) handles which error needs to be addressed (based on priority/order).
41: const validations = {
43: // goal is to return true, then try the next validation requirement (order matters)
44: required: function(value) {
45: return value !== '';
46: },
47: special: function(value) {
48: return value.match(/[^a-zA-Z0-9]/g) == null;
49: },
50: restricted: function(value) {
51: return value.match(/[IiOoQq]/g) == null;
52: },
53: quantity: function(value) {
54: return value.length > 16;
55: },
56: };
The problem:
Due to this switch statement, it will stop handling future/additional errors, if the rule return value qualifies for a case condition. My goal is to allow the user to incur multiple errors (for this case, searching for "A*IQ&"), then when they submit the form, they'll receive alerts for each of the errors detected, not the highest priority.
179: switch( rules[error] ) {
189: case 'required':
I'm considering handling the error within an Object Literal, but would rather receive advice and (possibly) examples of different opinions.
UPDATE #1:
I was able to work around this as an FYI (https://codepen.io/jodriscoll/pen/XLKKwa?editors=0010), but I'm not happy with the "bloat" and wanted to use a better approach.
I would consider using an object to track errors that maybe looks something like this. This supports multiple errors of the same type.
let validations = {
isValid: false,
errors: [
{
type: 'required',
message: 'You must provide a phone number.'
},
{
type: 'quantity',
message: 'The quantity selected must be between x and y.'
}
]
}
Then you can refactor the switch statement to something more like this:
validations.errors.forEach((error) => {
switch(error.type){
case 'required':
// Do something.
break;
case 'quantity':
// Do something else
// etc...
}
})
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
I have a function that needs to pick out the color of a fruit and I have opted for a switch case statement. The problem is I'm not sure how to get the result out of the statement. Maybe I should get an if/else-statement instead?
Here is the code:
function fruitColor(fruit) {
switch(color) {
case "apple" : green;
break;
case "banana" : yellow;
break;
case "kiwi" : green;
break;
case "plum" : red;
break;
}
}
var result = fruitColor(plum);
I can't get the result and I'm not sure if I need a 'return' value or something like that.
The return statement ends function execution and specifies a value to be returned to the function caller. return MDN
There are a few missteps here aside from not returning a value. return is the facility to send a value back from a function, but in order for that to happen, no errors can occur. As it stands, the variable color is used in the switch statement, but it does not exist, perhaps because it was supposed to be fruit or vice versa. Further, the values in the resulting code for the case statements are basically just references to variables, and if there is no variable named green then it is just undefined. Perhaps you meant "green".
function fruitColor(fruit) {
//note that there was no value color here, there was only the accepted
//parameter fruit, which should either be used or changed to color
switch(color) {
case "apple" :
//needs quotes, green with no quotes is a variable reference
"green";
//note that simply using the string "green" doesn't accomplish anything though
//what we really need to do is send a value back, and in JavaScript you
//use the return keyword for that followed by the returning value
return "green";//like this
break;
case "banana" : "yellow";//^
break;
case "kiwi" : "green";//^
break;
case "plum" : "red";//^
break;
}
}
var result = fruitColor("plum");//needs quotes, plum would be a variable refernce
Personally, I prefer dictionaries for this type of work.
var fruitColors = {
apple : "green",
banana : "yellow",
kiwi : "green",
plum : "red"
};
var plumColor = fruitColors["plum"];//red
When coding, you always want to keep your code as high performance as possible. Now that I said that, let me give you some options to solve problems of this kind:
First, let’s go with your current solution and making it work.
function fruitColor(fruit) {
switch(color) {
case "apple" :
return 'green';
break;
case "banana" :
return 'yellow';
break;
case "kiwi" :
return 'green'
break;
case "plum" :
return 'red';
break;
}
}
var result = fruitColor(plum);
This one uses your switch construct and also returns prematurely, works.
However, it is not the best way to attack these kind of problems, because it generates code bifurcations that imply more memory is used to store and evaluate your code. Another way to do this is using an object with the fruits and colours.
function fruitColor(fruit) {
var fruits = {
apple : 'green',
banana : 'yellow',
kiwi : 'green',
plum : 'red'
};
return fruits[fruit] || 'not found';
}
var result = fruitColor('plum');
This code relies in a in-memory data base, works fast and has less bifurcations, but it also depends on a search.
This is my function implementation of the switch construct:
const fruitColor = fruit =>
({ apple: "green", banana: "yellow", kiwi: "green", plum: "red" }[fruit] ||
"Nothing");
I would like to add a following up to Travis J's answer.
From here I want to emphasise how you can put your arguments into the switch statement. The parameter variables fruit and color takes an argument. If you want an argument taken from the function fruitColor into the switch statement, use the same parameter variable name. I.e., either use fruit for both, or color for both.
function fruitColor(fruit) {
// Note that there was no value color here. There was only the accepted
// parameter fruit, which should either be used or changed to color
switch(color) {
case "apple":
"green";
return "green"; // Like this
break;
case "banana": "yellow"; // ^
break;
case "kiwi": "green"; // ^
break;
case "plum": "red"; // ^
break;
}
}
var result = fruitColor("plum");
First of all, in the switch statement, you have got to use the fruit argument, not the color and then you need a variable to store your choice:
function fruitColor(fruit) {
switch(fruit) {
case "apple" : result = green;
break;
case "banana" : result = yellow;
break;
case "kiwi" : result = green;
break;
case "plum" : result = red;
break;
}
return result;
}
var result = fruitColor(plum);