javascript string expression as if condition - javascript

I am building a string which is to be evaluated as if condition, like
if (location_val.length == 1) {
condition = condition + " v.location === '" + location_val + "' &&";
} else {
for (var i = 0; i < location_val.length; i++) {
condition = condition + " v.location === '" + location_val[i] + "' && ";
}
}
but javascript evaluates the variable if it is not null, undefined, 0 or empty string, how to evaluate string as expression? I am using condition variable as follows, but it always returns true because of the above reason.
if(condition)

Build your expression properly - not using string concatenation, its something like this:
var condition = (location_val.length == 1 && v.location == location_val)
|| (location_val.every(function(loc){ return v.location === loc; } );
if(condition) {
....
}
I suspect there is more to this (you have && at the end of both strings) but the same applies to everything else. Boolean's can be combined in parts
var condition1 = (location_val.length == 1 && v.location == location_val)
|| (location_val.every(function(loc){ return v.location === loc; } );
var condition2 = ...
var condition3 = ...
if(condition1 && condition2 && condition3){
....
}

In JavaScript there's the eval function. You can use it to evaluate a string as an expression.
eval('3 + 2 === 5') //true
I would recommend you to rethink your solution, though, since working with strings as expressions when you could solve your problem differently, is really error prone and literally the worst practise.
Also use === instead of ==
(=== works as you'd expect == to work, == doesn't)

Related

Valid Parentheses. Gives a wrong boolean (JS problems on LeetCode)

Trying to solve a problem at LeetCode called "Valid Parentheses".
Conditions are:
Given a string s containing just the characters '(', ')', '{', '}',
'[' and ']', determine if the input string is valid.
An input string is valid if:
Open brackets must be closed by the same type of brackets. Open
brackets must be closed in the correct order.
I wrote a function and it's working in this snippet:
let arr = ['()']
var isValid = function (data) {
let stack = [];
const bracketsArray = {
'{':'}',
'[':']',
'(':')'
}
for (i=0; i < data[0].length; i++) {
if (data[0][i] == '{' || data[0][i] == '(' || data[0][i] == '[') {
stack.push(data[0][i]);
} else if (data[0][i] == '}' || data[0][i] == ']' || data[0][i] == ')') {
if (bracketsArray[stack[stack.length-1]] == data[0][i]) {
stack.pop()
}
}
}
if (stack.length == 0) {
return true
} else {
return false
}
}
console.log(isValid(arr))
Function gives a correct output (boolean)
But when I run this code at LeetCode for some reason the same code gives me a wrong boolean.
Don't understand what is wrong.
/**
* #param {string} s
* #return {boolean}
*/
var isValid = function(s) {
let stack = [];
const bracketsArray = {
'{':'}',
'[':']',
'(':')'
}
for (i=0; i < s[0].length; i++) {
if (s[0][i] == '{' || s[0][i] == '(' || s[0][i] == '[') {
stack.push(s[0][i]);
} else if (s[0][i] == '}' || s[0][i] == ']' || s[0][i] == ')') {
if (bracketsArray[stack[stack.length-1]] == s[0][i]) {
stack.pop()
}
}
}
if (stack.length == 0) {
return true;
} else {
return false;
}
};
Any advice?
On LeetCode the function parameter is a string, but in your tests you are passing an array, and also your function code expects an array, since it accesses the string with s[0], instead of s.
Unrelated, but:
Your code fails when the input is just a closing bracket. This is because your loop doesn't break with return false when a non-matching closing bracket is encountered. This should happen in the else part of if (bracketsArray[stack[stack.length-1]] == s[i]) {
Don't use an undeclared variable i, which will then implicitly become a global variable (if running in non-strict mode).
Don't name your variable bracketsArray since it is not an array.
Make more use of that object, instead of making three comparisons with opening brackets.
The final if...then is overkill for just returning the value of a boolean expression.
So:
var isValid = function(s) {
const stack = [];
const brackets = {
'{':'}',
'[':']',
'(':')'
}
const closing = Object.values(brackets);
for (let ch of s) {
if (brackets[ch]) {
stack.push(brackets[ch]);
} else if (ch == stack.at(-1)) {
stack.pop()
} else if (closing.includes(ch)) {
return false;
}
}
return !stack.length;
};
console.log(isValid("{([])}")); // true
console.log(isValid("]")); // false
The way you are accessing the current character of the iteration is wrong. Instead of doing s[0][i], simply do s[i].
s[0][i] accesses the first character, and then attempts to get the i-th entry from it (which is undefined).
var isValid = function(s) {
let stack = [];
const bracketsArray = {
'{':'}',
'[':']',
'(':')'
}
for (i=0; i < s.length; i++) {
if (s[i] == '{' || s[i] == '(' || s[i] == '[') {
stack.push(s[i]);
} else if (s[i] == '}' || s[i] == ']' || s[i] == ')') {
if (bracketsArray[stack[stack.length-1]] == s[i]) {
stack.pop()
}
}
}
if (stack.length == 0) {
return true;
} else {
return false;
}
};
isValid("{([])}") // true
isValid("{([)}") // false

Evaluate string giving boolean expression in JavaScript

I have a string that contains Boolean logic something like:
var test = "(true)&&(false)&&!(true||true)"
What is a good way to evaluate this string in JavaScript to get the boolean value of false in this case
I know we could use eval() or new Function().. - but is that a safe approach?
I am guessing the other option would be to write a custom parser. Being a fairly new person to JS, would that be a lot of effort? I could not find any examples of parsers for Boolean logic expressions
Any other alternatives?
As long as you can guarantee it to be safe, I think you could use eval.
Maybe by treating it before doing an eval?
var test = "(true)&&(false)&&!(true||true)"
var safe = test.replace(/true/ig, "1").replace(/false/ig, "0");
var match = safe.match(/[0-9&!|()]*/ig);
if(match) {
var result = !!eval(match[0]);
}
Javascript has a ternary operator you could use:
var i = result ? 1 : 0;
Here, result is Boolean value either True or False.
So, Your question will be something like that after this operation.
(1)&(0)&!(1||1)
I hope you can better evaluate now this Boolean logic.
you can use eval,
Eg: eval("(true)&&(false)&&!(true||true)");
Try this code
function processExpression(expr)
{
while (expr.indexOf("(" ) != -1 )
{
expr = expr.replace(/\([\w|]+\)/g, function(matched){ return processBrace(matched)});
}
return expr = processBrace( "(" + expr + ")" );
}
function processBrace(str)
{
return str.substring(1).slice(0,-1).split(/(?=&|\|)/).map(function(value,index,arr){
if ( index != 0 && index%2 == 0 ) { return arr[index-1] + value } else if(index==0){return value;} else {return ""}
}).filter(function(val){return val.length > 0}).reduce(function(prev,current){
var first = Boolean(prev);
var operator = current.substring(0,2);
var operand = current.substring(2);
while ( operand.indexOf("!") != -1 )
{
var boolval = operand.match(/\w+/)[0] == "false"; //flip the value by comparing it with false
var negations = operand.match(/\W+/)[0];
operand = negations.substring(1) + boolval;
}
var second = operand == "true";
var output = operator == "&&" ? (first && second) : (first || second);
return output;
});
}
DEMO
function processExpression(expr)
{
while (expr.indexOf("(" ) != -1 )
{
expr = expr.replace(/\([\w|]+\)/g, function(matched){ return processBrace(matched)});
}
return expr = processBrace( "(" + expr + ")" );
}
function processBrace(str)
{
return str.substring(1).slice(0,-1).split(/(?=&|\|)/).map(function(value,index,arr){
if ( index != 0 && index%2 == 0 ) { return arr[index-1] + value } else if(index==0){return value;} else {return ""}
}).filter(function(val){return val.length > 0}).reduce(function(prev,current){
var first = Boolean(prev);
var operator = current.substring(0,2);
var operand = current.substring(2);
while ( operand.indexOf("!") != -1 )
{
var boolval = operand.match(/\w+/)[0] == "false"; //flip the value by comparing it with false
var negations = operand.match(/\W+/)[0];
operand = negations.substring(1) + boolval;
}
var second = operand == "true";
var output = operator == "&&" ? (first && second) : (first || second);
return output;
});
}
var example1 = "(true)&&(false)&&!(true||true)";
document.body.innerHTML += example1 + " -- " + processExpression(example1);
Try using "".match() in ternary operator condition
"(true)&&(true)&&!(true||true)".match(/false/ig)?false:true

Why is `exp && "t" || "f"` much slower than inline-if-else?

Why is the logical expression twice slower than if-else or inline-if-else?
function logicalExp(val) {
return val && "t" || "f";
}
function inlineIfElse(val) {
return val ? "t" : "f";
}
function ifElse(val) {
if (val) return "t";
else return "f";
}
All functions evaluate with same results.
All functions are being passed a value from an array of 1 and 0, see this jsperf test.
Because it does need to evaluate whether "t" is truthy or not. The short-circuit expression return ((val && "t") || "f") can be expanded to
var and = val ? "t" : val;
var or = and ? and : "f";
return or;
Of course, an optimising compiler could statically determine the truthiness of the "t" literal, and avoid doing ToBoolean(val) twice, but apparently this is not done in any JS engine.
Because
val && "t" || "f"
has to evaluate val and, if val evaluates to true, "t" as well.
Using only false is therefore significantly faster than only true, but still quite slow.

DashInsert Coderbyte Challenge - Why does arr[i]%2===1 work?

The Coderbyte problem is:
Using the JavaScript language, have the function DashInsert(str) insert dashes ('-') between each two odd numbers in str. For example: if str is 454793 the output should be 4547-9-3. Don't count zero as an odd number.
So when the input is 99946, the output should be 9-9-946.
I had this solution, which wouldn't quite work:
function DashInsert(num) {
var arr = num.toString().split('');
var i = 0;
while(i < arr.length-1){
if( arr[i]%2 !==0 && arr[i+1]%2 !==0){
arr.splice(i+1,0,'-');
}
i++
}
return arr.join('');
}
Then I found this similar answer:
function DashInsert(num) {
var arr = num.toString().split('');
var i = 0
while(i < arr.length-1){
if( arr[i]%2===1 && arr[i+1]%2===1){
arr.splice(i+1,0,'-');
}
i++
}
return arr.join(''); }
str = 99946;
alert(DashInsert(str));
Can anyone explain why it should be arr[i]%2===1?
both are correct .
for example , take 9 : 9%2 != 0 and also 9%2 ==1 . think about it , all odd numbers can be split to
2n+1 . a modulo of 2 will always return 1 , which is not 0.
For anyone else who stumbles upon this in a frustrated googling haze...
After the first hyphen is added, it changes the length of the array, so it gets evaluated in the loop to see if the hyphen element !== 0.
Since a '-' !== 0, another hyphen is added.
This is also why you keep blowing your stack since the hyphen keeps changing the length of your array (side note, always cache your length in a variable outside of your for loop and use that in your loop instead).
To fix it, you could add a bunch more &&'s to your if statement i.e.
if(theArray[x] % 2 !== 0 && theArray[x+1]% 2 !== 0 && theArray[x] !== '-' && theArray[x+1] !== '-')
or you could just be more specific and only look for modulo results that evaluate to 1.
I tried this and it works..
HTH..
private static String createDashedString(String str) {
StringBuilder builder = new StringBuilder();
char[] chararray = str.toCharArray();
for (int i=0;i<chararray.length-1;i++) {
int firstInt = Character.getNumericValue(chararray[i]);
int nextInt = Character.getNumericValue(chararray[i+1]);
if ((firstInt%2 !=0) && (nextInt%2 !=0)) {
builder.append(firstInt);
builder.append("-");
}else {
builder.append(firstInt);
}
}
builder.append(chararray[chararray.length-1]);
return builder.toString();
}
public static void main(String args[]) {
String str = "999999";
//01234
System.out.println(createDashedString(str));
}
function DashInsert(str) {
let bil = 0;
while (bil < str.length-1) {
if (Number(str[bil]) % 2 === 1 && Number(str[bil+1]) % 2 === 1) {
str = str.slice(0,bil+1) + "-" + str.slice(bil+1);
bil = bil + 2;
}
else {
bil++;
}
}
return str;
}
console.log(DashInsert("454793"));
let x = '99946'
let z=[]
for(var i = 0;i<x.length;i++){
if(x[i]%2 == 0 && x[i+1]%2 == 1 ){
z+=x[ i ]
}else if (x[i]%2 == 1 && x[i+1]%2 == 0){
z+=x[i]
}else if (x[i]%2 == 1 && x[i+1]%2 == 1){
z+=x[i]+"-"
}else{
z+=x[i]
}
}
console.log(z)

jQuery function for check textbox

I’d like use jquery function that validate a input field. This input field must be used for entering 11 digit numbers that start with 0.
I tried some function but doesn’t work!
function check(mob) {
var firstnum = mob.substring(1);
alert(firstnum);
if (firstnum != "0" || mob.lenght != 11)
return false;
else
return true;
}
function check(mob) {
return mob.substring(0, 1) == '0' && mob.length == 11;
}
String Method Reference
If you want to check is it 11 digit, you should use RegExp
function check(mob) {
return mob.match(/^0\d{10}$/) != null;
}
You need to use .charAt(0) to get the first character of a string. .substring(1) will return the rest of the string minus the first character.
"01234567890".substring(1) = "1234567890"
"01234567890".charAt(0) = "0"
"01234567890".length = 11 (assuming that you have spelled "length" correctly in your code)
Edit: Since you also need to check for digits, you could use a regular expression to verify this (although the whole check could also be done with a regex)
The completed function could therefore be simplified to just:
function isValidMobile(mobileNumber) {
return mobileNumber.charAt(0) == 0 && mobileNumber.length === 11 && /^\d+$/.test(mobileNumber);
}
Or without the regex
function isValidMobile(mobileNumber) {
return mobileNumber.charAt(0) == 0 && mobileNumber.length === 11 && !isNaN(mobileNumber);
}
if (firstnum >= 1 || mob.lenght <= 11) //lenght spell wrong
change to
if (firstnum >= 1 || mob.length<= 11)
you can give it a try
function check(mob) {
var num = parseInt(mob);
if (mob+'' == '0'+num && mob.length == 11)
return true;
else
return false;
}
here what I am doing is that parseInt will give you exact same number without 0 if all characters are numbers, so in the condition I am just adding 0 in starting and checking with mobile number , it will do 2 validation in once , all are number starts with 0 and next validation is for length
Try using a simple regex as below
function check(mob) {
return /^0\d{10}$/.test(mob)
}
function check(mob) {
if(!isNaN(mob)){ // or use parseInt
var firstnum = mob.charAt(0);
alert(firstnum);
if (firstnum != "0" || mob.length != 11) {
return false;
} else {
return true;
}
}
}

Categories

Resources