본문 바로가기

Programing/JavaScript

[JavaScript] eval()을 사용하지 않고 문자열로된 식 계산하기

eval()을 사용하면 보안상 문제가 생길 수 있어 쓰지않는게 좋다고한다.

알고리즘 문제를 풀다가 문자열로된 식을 계산해야 했었는데

eval을 대체할 것이 있나 찾다가 뭔소린지 이해 못하겠어서 eval 대체 함수를 만들었다.


eval() 을 사용하지 않고 문자열로된 식을 계산하는 function

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
 
// eval() 을 사용하지 않고 문자열로된 식을 계산하는 function이다.
// 결과값은 숫자로 나온다.
 
function calculateStrSum(strSumFormula) {
    // strSumFormula가 '156+78+58-115-587+5-4+1+2'라고 가정할 때,
    
    var exceptPlusStrArrButHaveMinus = strSumFormula.split('+'); 
    // strSumFormula 문자열을 split으로 '+'을 빼고 배열로 만들어준다.
    // 하지만 '-'는 있다 => exceptPlusStrArrButHaveMinus = [ '156', '78', '58-115-587', '5-4', '1', '2' ]
    var containMinusStrArr = [];
    var remainStrArr = [];
    var minusValueArr = [];
    var minusValue = 0;
    var minResultArr = [];
    var totalArr = [];
    var result = 0;
    
    exceptPlusStrArrButHaveMinus.forEach(elem => {
      if(!Number(elem)) {
        containMinusStrArr.push(elem); // exceptPlusStrArrButHaveMinus 배열 안의 값중에서 -가 껴있는 값만 
        // containMinusStrArr에 넣어준다. => [ '58-115-587', '5-4' ]
      } else {
        remainStrArr.push(Number(elem)); // 그 이외 나머지 수식이 붙지 않은 양수 값들은 
        // Number로 바꾸어 remainStrArr에 넣는다.
      } // remainStrArr = [ 156, 78, 1, 2 ]
    });
    
    containMinusStrArr.forEach(elem => { // containMinusStrArr에서 split('-') 하여 만들어진 배열을 
                                         // minusValueArr에 넣어 줄것이다.
      elem = elem.split('-');
      // console.log(elem); // => [ '58', '115', '587' ] [ '5', '4' ] 두번 나오게된다.
      
      minusValueArr.push(elem); // minusValueArr = [ [ '58', '115', '587' ], [ '5', '4' ] ]
    });
    
    minusValueArr.forEach((elem, i) => {
      minusValue = Number(elem[0]);  // minusValueArr의 elem의 [0]값은 양수 이므로 Number로 바꿔 따로 지정해준다.
      for(var j = 1; j < elem.length; j++) {
        minusValue -= Number(elem[j]); // elem[0]에서 elem[j]까지 값을 빼준다. 그 값은 minusValue가 된다.
      } minResultArr.push(minusValue);  // minus값이 모두 계산되면 minResultArr에 넣는다.
    }); // minResultArr = [ -644, 1 ]
    
    totalArr = remainStrArr.concat(minResultArr); 
    // 양수만 있는 arr인 remainStrArr와
    // minus가 계산된 값의 arr minResultArr를 concat한다. // => totalArr =  [ 156, 78, 1, 2, -644, 1 ]
    
    totalArr.forEach(elem => {
      result += elem;
    }); // totalArr의 모든 값을 더하여 result에 넣는다.
    
    /*
    console.log(exceptPlusStrArrButHaveMinus);
    console.log(containMinusStrArr);
    console.log(remainStrArr);
    console.log(minusValueArr);
    console.log(minResultArr);
    console.log(totalArr); */
    
    return result; // => -406
    
}
  
var str = '156+78+58-115-587+5-4+1+2';
calculateStrSum(str);
 
cs




주석없앤 위의 function

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
 
function calculateStrSum(strSumFormula) {
    
    var exceptPlusStrArrButHaveMinus = strSumFormula.split('+'); 
    var containMinusStrArr = [];
    var remainStrArr = [];
    var minusValueArr = [];
    var minusValue = 0;
    var minResultArr = [];
    var totalArr = [];
    var result = 0;
    
    exceptPlusStrArrButHaveMinus.forEach(elem => {
      if(!Number(elem)) {
        containMinusStrArr.push(elem); 
      } else {
        remainStrArr.push(Number(elem)); 
      } 
    });
    
    containMinusStrArr.forEach(elem => { 
      elem = elem.split('-');
      
      minusValueArr.push(elem); 
    });
    
    minusValueArr.forEach((elem, i) => {
      minusValue = Number(elem[0]); 
      for(var j = 1; j < elem.length; j++) {
        minusValue -= Number(elem[j]); 
      } minResultArr.push(minusValue);  
    }); 
 
    totalArr = remainStrArr.concat(minResultArr); 
    
    totalArr.forEach(elem => {
      result += elem;
    }); 
    
    return result; 
    
}
  
var str = '156+78+58-115-587+5-4+1+2';
calculateStrSum(str);
 
cs




번외로 수식이 양수로만 되어있는 문자열을 계산할 때 function

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
 
// eval() 을 사용하지 않고 문자열로 되었고 +만 사용된 식을 계산하는 function이다.
// 결과값은 숫자로 나온다.
 
function calculateStrSum(strSumFormula) {
    var exceptPlusStrArr = strSumFormula.split('+'); 
    // strSumFormula 문자열을 split으로 '+'을 빼고 배열로 만들어준다.
    var convertNumArr = [];
    var sumResult = 0;
    
    // strSumFormula가 '156+78+58+115'라고 가정할 때,
    // exceptPlusStrArr = [ '156', '78', '58', '115' ]
    exceptPlusStrArr.forEach(elem => {     // exceptPlusStrArr안의 값을 숫자로 바꾼다.
      convertNumArr.push(Number(elem));    // convertNumArr = [ 156, 78, 58, 115 ]
    });
    
    convertNumArr.forEach(elem => {   // convertNumArr 안의 값을 모두 더하여
      sumResult += elem;              // sumResult에 넣는다.
    });
  
    return sumResult;  // => 407
  }
  
  var str = '156+78+58+115';
  calculateStrSum(str);
  
cs



=> 관련문제