[TIL] 240515 (React My Todo List 컴포넌트 분리 / 프로그래머스 옹알이 (2))

·2024년 5월 15일

TIL

목록 보기
42/268
post-thumbnail

🥞 오늘 한 일

  • 리액트 입문주차 개인과제
    • 컴포넌트 나누기
  • 자바스크립트 예제 30제
    • 5주차: DOM, class, 클로저 완료
  • 알고리즘 코드카타
    • 옹알이 (2)

리액트 입문주차 개인과제

컴포넌트 나누기

입문 과제 가이드를 제공받은 후, 가이드에서는 생각보다 컴포넌트를 많이 나눈다는 것을 알게 되었다. 기능은 이미 다 구현이 되었고 반드시 수정이 필요한 것은 아니었지만, 어차피 시간도 좀 남았고, 하라는대로 해서 나쁠 건 없다고 생각해서 진행하게 되었다.
기존의 컴포넌트는 다음과 같았다.

  • App.jsx
  • Todo.jsx
  • Button.jsx

우선 전체적으로 코드가 거의 다 App.jsx에 몰려 있었고, Todo.jsx 파일은 각 todo item에 대한 컴포넌트였다. Button.jsx 파일은 강의에서 분리하는 걸 보았기에 컴포넌트로 만들었다.
특별히 더 나눌 필요가 없다고 생각했으나, 가이드를 보고 더 세부적으로 나누게 되었다. 수정한 컴포넌트는 다음과 같다.

  • App.jsx
  • TodoContainer.jsx
  • TodoForm.jsx
  • TodoList.jsx
  • TodoItem.jsx (Todo.jsx에서 변경)
  • Button.jsx

(편의상 .jsx는 생략하도록 한다.)
우선 App에 있던 코드들을 TodoContainer에 몰아 넣고, App 파일에서는 TodoContainer만 import해서 넣어주었다. 제목 및 내용을 입력하는 TodoForm 컴포넌트, 각 리스트를 화면에 나타내는 TodoList 컴포넌트를 만들었고, 기존의 Todo 컴포넌트는 파일명이 직관적이지 않아 TodoItem으로 변경했다. 그리고 기존의 Button까지 총 6개의 컴포넌트가 제작되었다.
확실히 느낀 장점은 컴포넌트가 나뉘어있으니 좀 더 각 코드가 무슨 역할을 하는지 알아보기 쉽다는 점이다.

🍽️ 문제 해결

알고리즘 코드카타

옹알이 (2)

문제

머쓱이는 태어난 지 11개월 된 조카를 돌보고 있습니다. 조카는 아직 "aya", "ye", "woo", "ma" 네 가지 발음과 네 가지 발음을 조합해서 만들 수 있는 발음밖에 하지 못하고 연속해서 같은 발음을 하는 것을 어려워합니다. 문자열 배열 babbling이 매개변수로 주어질 때, 머쓱이의 조카가 발음할 수 있는 단어의 개수를 return하도록 solution 함수를 완성해주세요.

문제점

우선 내가 작성한 코드이다.

function solution(babbling) {
  let arr = ["aya", "ye", "woo", "ma"]
  for (let i=0; i<babbling.length; i++){
    for (let j=0; j<arr.length; j++){
      if (babbling[i].includes(arr[j])){
        babbling[i] = babbling[i].replace(arr[j], "");
      }
    }
  }
  return babbling.filter((item)=>item==="").length;
}

상당히 많은 테스트 케이스에서 실패했다. 100점 중 55점. 그래서 일단 질문하기 페이지에서 살펴보다가, 한 번씩만 replace되기 때문에 같은 발음이 반복될 경우 replace 되지 않는 문제점이 있었다. 때문에 replaceAll로 수정해보았다.

해결 과정 1

babbling[i] = babbling[i].replaceAll(arr[j], "");

이제 같은 발음이 여러 개일 경우의 문제는 해결되었다. 그러나 문제는 "yeye"처럼 같은 발음이 연속으로 있을 경우에는 발음이 불가능하다는 것이다. 때문에 연속된 발음일 경우의 조건을 추가하면 되지 않을까 하는 가설을 세워보았다.

해결 과정 2

function solution(babbling) {
    let newBabbling = [...babbling];
    let arr = ["aya", "ye", "woo", "ma"]
    for (let i=0; i<babbling.length; i++){
        for (let j=0; j<arr.length; j++){
            if (babbling[i].includes(arr[j]+arr[j])){
                continue;
            } else if (babbling[i].includes(arr[j])){
                newBabbling[i] = newBabbling[i].replaceAll(arr[j], "");
            }
        }
    }
    return newBabbling.filter((item)=>item==="").length;
}

우선 연속되는 발음이 있을 경우 replace 되지 않게 하는 조건문을 세웠고, 따로 떨어져있다가 다른 요소가 replace되어 연속되는 발음이 될 경우를 대비해 기존 배열을 복사해 새로운 배열에서 값을 변경하도록 했다. 이 조건으로 했을 경우 75점이 나왔고, 아까보단 나아졌지만 여전히 여러 테스트 케이스에서 실패했다. (1,11,14,16,17)
슬슬 머리가 아파오기 시작했다... 대체 뭐가 문제인가? 하다가 질문하기 페이지에서 반례를 보았다. 만약 babbling의 요소가 "ayamayaa"일 경우, 내 방식을 사용하면 "ayamayaa"=>"ma"=>"" 순서로 변한다. 원래는 "yaa"만 남아야하기 때문에, 이 방법은 잘못됐다고 생각했다. 그러면 어떻게 해야하는가? 이 역시도 질문하기 페이지에서 팁을 얻어 해결했다. 결국 여러 도움을 받고 풀었지만, 직접적인 정답에 대한 힌트를 받진 않았다. 결과적인 코드는 다음과 같다.

해결

function solution(babbling) {
    let newBabbling = [...babbling];
    let arr = ["aya", "ye", "woo", "ma"]
    for (let i=0; i<babbling.length; i++){
        for (let j=0; j<arr.length; j++){
            if (babbling[i].includes(arr[j]+arr[j])){
                continue;
            } else if (babbling[i].includes(arr[j])){
                newBabbling[i] = newBabbling[i].replaceAll(arr[j], " ");
            }
        }
        newBabbling[i] = newBabbling[i].replaceAll(" ","")
    }
    return newBabbling.filter((item)=>item==="").length;
}

replaceAll 시 지워주는 방법을 사용했는데, 이 때 ""가 아닌 " "로 변경하여, 공백을 넣어주었다. 이렇게 했을 경우 "ayamayaa"는 " m a"가 되기 때문에, replace되지 않는다. 그리고 나중에 다시 공백 문자열을 ""로 replace 시켜줘서 정답을 이끌어낼 수 있었다.
역대급으로 어렵게 푼 문제였다. 하지만 이런 류의 문제를 푸는 데에 있어서 약간의 힌트를 얻고 가는 것 같아서, 성장에 도움이 된 것 같아 만족스럽게 생각한다.

다른 사람의 풀이

function solution(babbling) {
  const regexp1 = /(aya|ye|woo|ma)\1+/;
  const regexp2 = /^(aya|ye|woo|ma)+$/;

  return babbling.reduce((ans, word) => (
    !regexp1.test(word) && regexp2.test(word) ? ++ans : ans
  ), 0);
}

정규식으로 하면 이렇게 간단하게 풀릴 수 있는 거였다... 확실히 정규식은 공부해두면 정말 도움이 많이 될 것 같기는 하다. 하지만 당장의 내 실력을 키우기 위해서는 위의 방법을 사용하는 것이 더 좋을 것이라고 생각한다...^^

🍴 느낀 점

리액트의 장점은 역시 컴포넌트 분리에 있다. 컴포넌트를 나누니 훨씬 보기가 좋고 이해가 쉽다.

🍳 내일 할 일

  • 리액트 입문주차 개인과제
    • 개인과제 해설 기반 과제 개선

🐱

profile
웹 프론트엔드 개발자

0개의 댓글