JavaScript/알고리즘

프로그래머스 간단한 식 계산하기 JS ("연산자"처리하기, if문/switch문/객체 이용하기, eval()은 ❌)

hihiha2 2023. 6. 16. 17:59
반응형

문제 설명

문자열 binomial이 매개변수로 주어집니다. binomial은 "a op b" 형태의 이항식이고 a와 b는 음이 아닌 정수, op는 '+', '-', '*' 중 하나입니다. 주어진 식을 계산한 정수를 return 하는 solution 함수를 작성해 주세요.

 

 

 

🙋‍♀️ 내 생각

이 문제의 핵심은 가운데 위치하고 있는 연산자를 어떻게 처리할 것인가라고 생각했다.

공백을 기준으로 하여 각각의 값을 구분하고 나누는것은 어렵지 않은데, 연산자도 문자열로 바뀌기때문에 string타입의 연산자를 어떻게해야 연산의 기능을 수행하도록 만들것인가를 생각하는 문제이다.

 

split(' ')을 통해서 공백을 기준으로 값을 구분하고, 배열에 담으면 아래와 같이 나온다.

숫자는 String을 Number타입으로 변환해주면 되지만, 연산자는 어떤 방법을 통해야하는지 몰라서 한참을 생각했다.

(검색해보니 eval을 쓰면 엄청 간단하지만 보안상의 문제로 좋지 않은 방법이라고 한다)

 

 

그래서 저 ""문자열로 감싸진 연산자를 어떻게 처리할까 고민하다가 나는 if문을 통해서 케이스를 나눠서 각각의 경우에 맞는 연산을 수행해주도록 했다.

 

 

 

 

✅ 내 코드

function solution(binomial){
    const [a,op,b] = binomial.split(' ')
    let Num1 = Number(a)
    let Num2 = Number(b)
    
    let result;
    if(op === '+'){
        result = Num1 + Num2
    } else if(op === '-'){
        result = Num1 - Num2
    } else if(op === '*'){
        result = Num1*Num2
    }
    return result
}

우선, split(' ')을 통해서 공백을 기준으로 binomial의 값을 나눠서 배열에 담는다.

값이 위와 같은 형식으로 나누어지는데, +연산자를 처리해주기 위해서는 각각 다른 처리를 해주어야한다.

그래서 각각 다른 변수에 할당하기 위해서 구조분해할당을 해주었다.

 

🔫 배열 구조분해할당 

주어진 배열을 분해하여 각각의 요소를 변수에 할당

const [a, op, b] = binomial.split(' ')

을 다시쓰면, 아래와 같다.

const [a, op, b] = ["43","+","12"]

 

 

각각 다른 변수에 할당을 해준다음, a와 b만 Number()를 통해 숫자타입으로 변환한다.

 

최종 결과값이 될 result를 선언한다.

 

그 다음, if문을 통해서 op가 "+"인 경우, "-"인 경우, "*"인 경우로 나눈다.

그리고 각각의 연산자에 맞는 연산을 수행해서 그 값이 result에 담기도록 해준다.

 

마지막으로 최종값인 result를 리턴한다.

 

if문의 마지막 요소인 *을 처리할때는 else를 사용해도 되지만, 코드의 가독성이나 유지보수의 측면에서 조건을 명확하게 적어주는게 좋은게 아닐까?하는 생각으로 마지막조건도 else if문으로 적었다. 결과는 똑같지만, 협업이나 프로젝트시에 더 좋은 코드가 있지 않을까? 더 공부를 해봐야겠다.

 

 

 

💻  다른사람 코드중에 배울 것 1 

function solution(binomial) {
    var answer = 0;
    const s = binomial.split(" ");
    const n1 = parseInt(s[0]);
    const n2 = parseInt(s[2]);

    switch(s[1]) {
        case "+" :
            return n1 + n2;
        case "-" :
            return n1 - n2;
        case "*" :
            return n1 * n2;
    }
}

기본적인 틀은 거의 유사하지만 크게 2가지가 달랐다.

1️⃣ 배열의 구조분해할당 대신에 인덱스를 이용하여 변수에 숫자값들을 할당하여 Number로 타입변환을 했고,

2️⃣ if문 대신에 switch문을 이용하여 케이스를 나눠서 처리했다.

 

 

🔫 Switch문

expression의 값을 평가하고, case 절과 일치하는 값을 찾으면 해당 case 문과 관련된 코드 블록을 실행

  • expression은 평가되어 얻은 결과와 case 절의 값들을 비교
  • 첫 번째 일치하는 case 문을 찾으면, 해당 case 문의 코드 블록을 실행
  •  break 문을 만나기 전까지 다음 case 문과 관련된 코드 블록도 순차적으로 실행
  • break 문을 만나므로 switch 문을 빠져나감
  • break 문을 사용하여 필요한 경우에만 원하는 동작을 수행하도록 제어
switch (expression) {
  case value1:
    // 코드 블록 A
    break;
  case value2:
    // 코드 블록 B
    break;
  case value3:
    // 코드 블록 C
    break;
  default:
    // 코드 블록 D
}

 

switch를 쓸 생각은 못했는데, 생각해보니 어차피 케이스를 나눠서 처리를 할거라면 switch를 쓰는게 더 좋을수도 있을 것 같다.

if문보다 가독성이 더 높아보인다.

 

 

💻  다른사람 코드중에 배울 것 2

const ops = {
  '+': (a, b) => a + b,
  '-': (a, b) => a - b,
  '*': (a, b) => a * b,
};

function solution(binomial) {
  const [a, op, b] = binomial.split(' ');
  return ops[op](+a, +b);
}

ops라는 이름의 객체를 만들고 key-value를 이용해서 케이스를 나누었다.

그리고 화살표함수를 통해 연산을 수행하도록하였다.

예를 들면 '+'라는 key값에는 (a,b) => a+b 로 합을 구하는 연산을 수행하도록 한다.

 

split(' ')으로 공백을 기준으로 값을 나눠서 배열에 담고, 배열의 구조분해할당을 통해 각각 a,op,b라는 변수에 할당하는것은 동일하다.

 

마지막으로 구조분해할당을 통해 만든 변수와 ops라는 객체를 이용해서 식을세운다.

자바스크립트에서 객체의 속성 에 접근할때는 일반적으로 2가지 방법을 사용하는데 '.'을 이용하는 dot 표기법과 '[]'를 이용하는 괄호표기법이다.

마지막줄의 +는 숫자로 타입변환을 해주기위함이다.

 

🔫 JS 객체의 속성에 접근하기

1. '.'표기법

  • key는 유효한 식별자여야 함
  • 정적인 property에 주로 사용
const obj = { a: 1, b: 2 };
console.log(obj.a); // 1
console.log(obj.b); // 2

2. '[]'표기법

  • key는 대괄호 안에 문자열 또는 계산된 표현식으로 전달
  • 동적인 property에 주로 사용
  • key가 변수, 식 또는 함수 호출을 통해 동적으로 결정되는 경우
const obj = { a: 1, b: 2 };
console.log(obj['a']); // 1
console.log(obj['b']); // 2

const propName = 'b';
console.log(obj[propName]); // 2

 

 

✔️ 일반적으로 . 표기법이 더 직관적이고 가독성이 좋으며, 대부분의 상황에서 사용하기에 적합하다. 하지만 동적인 속성 접근이 필요한 경우에는 [] 표기법을 사용하여 속성 이름을 동적으로 결정한다.

 

 

 

🙋‍♀️ 내 생각

switch문은 if문과 동작원리도 비슷하고 거의 유사한듯하다. 그래도 케이스 하나하나가 눈에 잘 들어와서 가독성이 높아지므로 앞으로 케이스를 나눠서 푸는 경우 switch문을 많이 활용해야겠다.

 

객체를 만들어서 케이스를 나눠서 각각의 케이스에 맞는 연산을 하도록 하는 생각은 못했는데, 이런식으로 객체로 나눠서 관리를 해도 눈에 잘 보이는것 같아서 알아두면 좋을 것같다. 

 

항상 문제를 풀고 이해하고 정리하면서 느끼지만 문제를 푸는 시간보다 공부하는 시간이 더 많이 든다. 다른사람들의 코드를 보면서 이런식으로하면 더 좋겠구나하는것도 배우고, 또 공식문서를 보면서  자바스크립트의 문법이나 메서드에 대해서 깊이있게 이해할 수 있어서 좋다.

한문제를 풀었지만 eval()은 보안상으로 좋지 않기때문에 간편해도 사용을 지양한다는 것, 배열의 구조분해할당, switch문, 객체를 이용한 case별 연산생성과 활용등 많은것을 배우고 또 알고 있는것은 더 정확하게 알도록 복습하였다.

반응형