Eval alternative

前端 未结 4 1623
-上瘾入骨i
-上瘾入骨i 2020-12-20 05:13

This code works as a calculator, but the scratch pad at codeacademy tells me that eval is evil. Is there another way to do the same thing without using eval?



        
相关标签:
4条回答
  • 2020-12-20 05:14

    eval evaluates the string input as JavaScript and coincidentally JavaScript supports calculations and understands 1+1, which makes it suitable as a calculator.

    If you don't want to use eval, which is good, you have to parse that string yourself and, finally, do the computation yourself (not exactly yourself though). Have a look at this math processor, which does what you want.

    Basically what you do is:

    1. Read the input string char by char (with this kind of problem it's still possible)
    2. Building a tree of actions you want to do
    3. At the end of the string, you evaluate the tree and do some calculations

    For example you have "1+2/3", this could evaluate to the following data structure:

         "+"
         /  \
       "1"  "/"
           /   \
         "2"   "3"
    

    You could then traverse that structure from top to bottom and do the computations. At first you've got the "+", which has a 1 on the left side and some expression on the right side, so you have to evaluate that expression first. So you go to the "/" node, which has two numeric children. Knowing that, you can now compute 2/3 and replace the whole "/" node with the result of that. Now you can go up again and compute the result of the "+" node: 1 + 0.66. Now you replace that node with the result and all you've got left is the result of the expression.

    Some pseudo code on how this might look in your code:

    calculation(operator, leftValue, rightValue):
       switch operator {
          case '+': return leftValue + rightValue
          case '-': return 42
       }
    
    action(node):
       node.value = calculation(node.operator, action(node.left) action(node.right))
    

    As you might have noticed, the tree is designed in such a way that it honors operator precedence. The / has a lower level than the +, which means it get's evaluated first.

    However you do this in detail, that's basically the way to go.

    0 讨论(0)
  • 2020-12-20 05:21

    You can use the expression parser that is included in the math.js library:

    http://mathjs.org

    Example usage:

    mathjs.evaluate('1.2 / (2.3 + 0.7)');   // 0.4
    mathjs.evaluate('5.08 cm in inch');     // 2 inch
    mathjs.evaluate('sin(45 deg) ^ 2');     // 0.5
    mathjs.evaluate('9 / 3 + 2i');          // 3 + 2i
    mathjs.evaluate('det([-1, 2; 3, 1])');  // -7
    
    0 讨论(0)
  • 2020-12-20 05:22

    You can use eval safely for a simple arithmetic calculator by filtering the input- if you only accept digits, decimal points and operators (+,-,*,/) you won't get in much trouble. If you want advanced Math functions, you are better off with the parser suggestions.

    function calculate(){
        "use strict";
        var s= prompt('Enter problem');
        if(/[^0-9()*+\/ .-]+/.test(s)) throw Error('bad input...');
        try{
            var ans= eval(s);
        }
        catch(er){
            alert(er.message);
        }
        alert(ans);
    }
    
    calculate()
    
    0 讨论(0)
  • 2020-12-20 05:28

    I write some functions when I had a problem like this. Maybe this can help:

    data = [
      {id:1,val1:"test",val2:"test2",val2:"test3"},
      {id:2,val1:"test",val2:"test2",val2:"test3"},
      {id:3,val1:"test",val2:"test2",val2:"test3"}
    ];
    datakey = Object.keys(data[0]);
    // here's a fix for e['datakey[f]'] >> e[x]
    vix = function(e,f){
    	a = "string";
    	e[a] = datakey[f];
    	x = e.string;
    	end = e[x];
    	delete e.string;
    	return end;
    };
    // here's a fix to define that variable
    vox = function(e,f,string){
    	a = "string";
    	e[a] = datakey[f];
    	x = e.string;
    	end = e[x] = string;
    	delete e.string;
    };
    row = 2 // 3th row ==> {id:3,val1:"test",val2:"test2",val2:"test3"}
    column = 1 //datakey 2 ==> val1
    vox(data[row],column,"new value");
    alert(data[2].val1); //the value that we have changed

    0 讨论(0)
提交回复
热议问题