0

Could someone tell me how can I make from regular text an if statement? Example:

let statement1 = "(5 < 10 < 15)"
let statement1 = createState(statement1); // output: true

let statement2 = "(50 < 100 < 150)"
let statement2 = createState(statement2); // output: true

let statement3 = "(5 > 10 > 15)"
let statement3 = createState(statement3); // output: false

let statement4 = "(50 > 100 < 150)"
let statement4 = createState(statement4); // output: false

function createState() {
  // code here...
}

I found this answer: If statement from string statement, but it is using eval and I don't want to use already built functions in JS P.S: the performance of the site will be slow if I'll use already built functions in JS

  • How complicated can these get? just numbers and `<`/`>`? what are the parentheses doing? By the way, you can't use `eval` without separating `5 < 10 < 15` to `5 < 10 && 10 < 15`, and you can't really say performance will be worse (even assuming you evaluate hudreds of these expressions). – Kobi Jul 17 '21 at 07:14
  • parentheses are just for example. If statement always has it, so I added them to the code for more people to understand what I want – Lev Shapiro Jul 17 '21 at 07:17
  • Just for fun, this is one solution: https://jsbin.com/xepexeqoku/2/edit?js,console I didn't post an answer because it still uses `eval` - but in a safe way (on a sanitizes expression). The code breaks the string into pairs and evaluates each pair. – Kobi Jul 17 '21 at 08:16

2 Answers2

2
const statement = "(50 < 100 < 150)"

you can use regular expressions to ignore parentheses and split numbers and operators

const splitedStatement = statement.match(/(\d+|<|>|=|<=|>=|!=)/g) // ["50", "<", "100", "<", "150"]

and then loop through it using built in reduce function

function createState(arg) {
  const regex = /(\d+|<|>|=|<=|>=|!=)/g;
  const operate = (num1, num2, opt) => {
    switch (opt) {
      case "=":
        return num1 === num2;
      case "!=":
        return num1 !== num2;
      case "<":
        return num1 < num2;
      case ">":
        return num1 > num2;
      case "<=":
        return num1 <= num2;
      case ">=":
        return num1 >= num2;
      default:
        break;
    }
  };
  return arg.match(regex).reduce((answer, item, index, array) => (index % 2 ? answer && operate(+array[index - 1], +array[index + 1], item) : answer), true);
}
0

There were some mistakes in your code which is also fixed, let don't allow re declaration of variable. And last statement "50 > 100 < 150" output to true.

let statement1 = "(5 < 10 < 15)"
statement1 = createState(statement1); // output: true

let statement2 = "(50 < 100 < 150)"
statement2 = createState(statement2); // output: true

let statement3 = "(5 > 10 > 15)"
statement3 = createState(statement3); // output: false

let statement4 = "(50 > 100 < 150)"
statement4 = createState(statement4); // output: false

function createState(arg) {
  // using substr() parenthesis got removed
  // split() is used to split string by space
  let parts = arg.substr(1, arg.length -2).split(" ");
  let output = "";
  if ( parts[1] == "<" && parts[3] == "<" ) {
    output = parts[0] < parts[2] < parts[4];
  } else if ( parts[1] == "<" && parts[3] == ">" ) {
    output = parts[0] < parts[2] > parts[4];
  } else if ( parts[1] == ">" && parts[3] == ">" ) {
    output = parts[0] > parts[2] > parts[4];
  } else if ( parts[1] == ">" && parts[3] == "<" ) {
    output = parts[0] > parts[2] < parts[4];
  }
  return output;
}
  • There are a few problems with this solution: you need to parse the strings to numbers (try `"10000" < "2"`), JavaScript doesn't support expressions like `parts[0] > parts[2] < parts[4]` (for example `1 > 2 < 3` is `false < 3`, `0 < 3`, `true`), and it doesn't scale well (if the OP needs `<=`/`>=`/`=`/`!=`) – Kobi Jul 17 '21 at 07:47
  • This solution is just for your provided statements which have two operators and 3 operands. Whereas javascript support these expressions i have tested "parts[0] > parts[2] < parts[4]" this. – Ali Raza Cheema Jul 17 '21 at 07:50
  • You can add as many "else if" for any operators "<= / >= / = / !=". – Ali Raza Cheema Jul 17 '21 at 07:53
  • I guess the code won't look good if there are many if/else there. It's like creating 100 elements in HTML, when with DOM JS you can simply loop through it and don't waste a lot of lines on that stuff... For now I only need > or <, but sometimes I'll need to do !=/ ===/ <=/ >= and it won't be the best idea to make if else for every one of it... – Lev Shapiro Jul 17 '21 at 09:12
  • HTML and DOM is different thing. In this situation where you don't want to use "eval()" we are left with only "if else" option. how can we achieve this with loop? If you study Compiler Construction and Lexical Parsers then you will learn how tokens parsing work. – Ali Raza Cheema Jul 17 '21 at 09:30
  • So you mean there is no other way? – Lev Shapiro Jul 17 '21 at 10:02
  • But eval function wasn't made with if else, right? – Lev Shapiro Jul 17 '21 at 10:04
  • Sir, to where my knowledge goes this is a good solution. I don't say this one is most optimized solution this can be optimized. If you have any other solution I am open to learning. – Ali Raza Cheema Jul 17 '21 at 10:18
  • "eval()" function runs any string as javascript statement/expression at the backend compiler is running which follows this approach I used break string into tokens and then use Conditional Statements to handle each operation. – Ali Raza Cheema Jul 17 '21 at 10:19