[Front-end] 개발자 공부

[개발 공부 50일차] substr(), Set | 가운데 글자 가져오기

MOLLY_ 2024. 3. 6. 02:30
728x90

< 목차 >
1. [09:00~10:00] 코드카타 문제 풀이
   - 가운데 글자 가져오기
2. substr()
3. Set
4. switch
5. 오늘 작성한 코드
6. 금일 소감

 
 

1. [09:00~10:00] 코드카타 문제 풀이
   - 가운데 글자 가져오기

문제 설명 및 실행 결과

 

 

문제 설명

: 단어 s의 가운데 글자를 반환하는 함수, solution을 만들어 보자. 단어의 길이가 짝수라면 가운데 두 글자를 반환하면 된다.

 


제한사항

: s는 길이가 1 이상, 100이하인 String

 

 

삼항연산자를 사용하는 것과 짝수임을 확인하기 위해 2로 나누었을 때 나머지가 0인 것을 구하는 것까진 알았다. 그런데 가운데 두 글자를 가져오려면 어떻게 해야 하지? 하는 생각이 들었다. 다른 답안을 찾다가 효율적으로 작성한 것으로 판단되고 또 substr을 사용한 사람들이 많길래 공부하고자 아래 답안으로 가져와서 이해하기 시작했다.

 

 

▼  답안 코드

function solution(s) {
    return s.length % 2 == 0 ? s.substr(s.length / 2 - 1, 2) : s.substr(s.length / 2, 1)
}

 

 

 

2. substr()

문자열의 특정 위치에서 시작하여 특정 문자 수만큼의 문자들을 반환

 

 

기본 형태

str.substr(start[, length])

 

 

사용 예시

const str = 'Mozilla';

console.log(str.substr(1, 2)); // oz
console.log(str.substr(2)); // zilla

 

 

start

추출하고자 하는 문자들의 시작 위치

만약 음수가 주어진다면, 문자열 총길이 + start의 값으로 취급한다.

ex) start에 -3을 설정하면 자동적으로 문자열 총길이 - 3으로 설정하게 된다.

 

 

length

옵션값. 추출할 문자들의 총 숫자

 

 

[Conference]

MDN 공식 문서: https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/String/substr

 

 

 

3. Set

유일한 값들을 모아놓은 컬렉션

여기서 "유일한 값들"이란, 어떤 값이 Set 내에 한 번만 존재한다는 뜻이며, 중복된 값을 저장할 수 없다.

 

Set의 핵심 특징

  • 유일성Set 내의 모든 값은 유일해야 한다. 같은 값을 추가하려고 하면, Set은 그 값을 무시한다.
  • 순서 유지: Set 내의 값들은 삽입된 순서를 유지한다. 하지만, 인덱스로 접근하는 것은 지원하지 않는다.
  • 접근성: Set에 값을 추가하거나 삭제, 조회할 때 사용할 수 있는 메서드가 있다. 예를 들어, .add(value), .delete(value), .has(value) 등이 있다.
  • 크기: Set.size 속성을 통해 Set 내의 값의 개수를 알 수 있다.

 


간단한 예시로, 숫자의 집합을 만들고 싶다고 가정해 보자.  Set은 주로 값의 유일성이 보장되어야 할 때 유용하게 사용된다.

 

사용 예시

let numbers = new Set();
numbers.add(1);
numbers.add(2);
numbers.add(3);
numbers.add(3); // 이 값은 무시된다. 왜냐하면, 3은 이미 Set에 존재하기 때문

console.log(numbers); // Set(3) {1, 2, 3}
console.log(numbers.has(2)); // true
console.log(numbers.size); // 3

 

 

 

4. switch

다중 조건을 효율적으로 처리할 수 있는 구문

여러 if-else if 문을 사용하는 대신에 switch를 사용하면 코드가 더 깔끔하고 이해하기 쉬워진다.

 


기본 구조

switch (표현식) {
  case 값1:
    // 값1이 표현식의 결과와 일치할 때 실행될 코드
    break;
  case 값2:
    // 값2가 표현식의 결과와 일치할 때 실행될 코드
    break;
  ...
  default:
    // 어떤 case도 일치하지 않을 때 실행될 코드
}

 

 

 

핵심 포인트

  • 표현식 평가: switch 문은 먼저 괄호 안의 표현식을 평가한다.
  • 값 매칭: 그 다음, 평가된 결과와 일치하는 case 레이블을 찾는다.
  • 코드 실행: 일치하는 case가 있다면, 해당 case의 코드 블록을 실행한다. 일치하는 case가 없다면, default 블록(있는 경우)이 실행된다.
  • break 문: 각 case 블록 끝에 break를 사용해서 switch 문에서 빠져나온다. break가 없으면, 다음 case의 코드도 실행되는 "폴스루(fall-through)"가 발생한다.
  • default 블록: 모든 case와 일치하지 않을 때 실행될 코드를 정의한다. default는 선택적으로 사용할 수 있으며, 위치는 switch 문 내 어디에 있어도 상관없지만, 주로 마지막에 위치시킨다.

 

 

사용 예시

let fruit = 'apple';

switch (fruit) {
  case 'banana':
    console.log('Yellow and bendy.');
    break;
  case 'apple':
    console.log('Crisp and sweet.');
    break;
  case 'orange':
    console.log('Tangy and round.');
    break;
  default:
    console.log('Unknown fruit.');
    break;
}

// [출력] Crisp and sweet.

 

이 예시에서 fruit 변수의 값은 'apple'이므로, 'apple'에 해당하는 case 블록이 실행된다. 각 case 끝에 있는 break는 switch 문에서 더 이상의 코드를 실행하지 않고 빠져나오게 한다.

 

 

 

5. 오늘 작성한 코드

React 숙련 과정을 2번째 재청강헀다. 중간 부분부터 마지막까지는 전에 재청강하며 복습했었는데, 초반부터 중반까지는 시간이 안 돼서 못했어서 이번에 다시 들으며 정리했다. 들으며 작성한 코드는 다음과 같다.

import './App.css';
import styled from 'styled-components';
import TestPage from './components/TsetPage';
import GlobalStyle from './components/GlobalStyle';
import { useCallback, useEffect, useRef, useState } from 'react';
import GrandFather from './components/GrandFather';
import Box1 from './components/Box1';
import Box2 from './components/Box2';
import Box3 from './components/Box3';
import HeavyComponent from './components/HeavyComponent';

const StContainer = styled.div`
    display: flex;
`;

const StBox = styled.div`
    width: 100px;
    height: 100px;
    border: 1px solid ${(props) => props.borderColor};
    margin: 20px;
`;

// 박스의 색
const boxList = ['red', 'blue', 'green', 'black'];

// 색을 넣으면 이름을 반환
const getBoxName = (color) => {
    switch (color) {
        case 'red':
            return '빨간 박스';
        case 'blue':
            return '파란 박스';
        case 'green':
            return '초록 박스';
        default:
            return '검정 박스';
    }
};

const style = {
    border: '1px solid black',
    margin: '10px',
    padding: '10px',
};

function App() {
    const [number, setNumber] = useState(0);
    const [value, setValue] = useState('');

    useEffect(() => {
        console.log(`Hello useEffect! : ${value}`);

        // return문 안에 작성하면 컴포넌트가 사라질 때 동작함
        return () => {
            console.log('나 사라져요!');
        };
    }, [value]);

    // ref: reference
    // reg로 만든 값은 컴포넌트가 계속 렌더링돼도 unmount 전까지 값을 유지함
    const ref = useRef('초기값');
    console.log('ref', ref);

    ref.current = '변경값';
    console.log('ref2', ref);

    // [1-5] useRef
    const [count1, setCount1] = useState(0);
    const countRef = useRef(0);

    const plusStateCountButtonHandler = () => {
        setCount1(count1 + 1);
    };

    const plusRefCountButtonHandler = () => {
        countRef.current++;
        console.log(countRef.current);
    };

    const idRef = useRef('');
    const pwRef = useRef('');

    const [id, setId] = useState('');

    // useEffect: 화면이 렌더링 될 때, 어떤 작업을 하고 싶다
    useEffect(() => {
        // 화면이 새로고침되면 커서를 id 입력칸에 포커싱 해줘
        idRef.current.focus();
    }, []);

    useEffect(() => {
        if (id.length >= 10) {
            pwRef.current.focus();
        }
    }, [id]);

    // [1-7] 최적화: React.memo
    // count + 1
    const onPlusButtonClickHandler = () => {
        setCount1(count1 + 1);
    };

    // count - 1
    const onMinusButtonClickHandler = () => {
        setCount1(count1 - 1);
    };

    // [1-8] 최적화: useCallback
    // count를 초기화해주는 함수
    // 특정 state가 변경될 때, 처음에 저장했던 state가 갱신되어야 하면 의존성 배열에 해당 state를 넣어놔야 함
    const initCount = useCallback(() => {
        console.log(`${count1}에서 0으로 변경되었습니다.`);
        setCount1(0);
    }, [count1]);

    return (
        <>
            <h2>React 숙련 1-1 ~ 1-11 복습용</h2>
            <StContainer>
                {/* [1-1, 1-2] 조건부 스타일링 */}
                {/* <StBox borderColor="red">빨간 박스</StBox> */}
                {boxList.map((box) => {
                    return (
                        <StBox key={box.id} borderColor={box}>
                            {getBoxName(box)}
                        </StBox>
                    );
                })}
            </StContainer>
            <GlobalStyle />
            <TestPage title="제목입니다" contents="내용입니다" />
            {/* [1-3] useState */}
            <div>Number State: {number}</div>
            <button
                onClick={() => {
                    // 기존 업데이트 방법
                    // 배치성으로 처리됨 = 배치 업데이트
                    // React에선 렌더링을 줄이기 위해 배치 업데이트 사용함
                    // 렌더링이 잦다 = 성능에 이슈가 있음을 의미

                    // setNumber(number + 1);
                    // setNumber(number + 1);
                    // setNumber(number + 1);

                    // 함수형 업데이트
                    // currentNumber에 +1을 해주기 때문에 여러 개를 작성하면 그 개수만큼 한꺼번에 실행됨
                    setNumber((currentNumber) => currentNumber + 1);
                    // setNumber((currentNumber) => currentNumber + 1);
                    // setNumber((currentNumber) => currentNumber + 1);
                }}
            >
                누르면 +1
            </button>
            {/* [1-4] useEffect */}
            <input
                type="text"
                value={value}
                onChange={(event) => {
                    setValue(event.target.value);
                }}
            />
            <div style={style}>
                state 영역입니다. {count1} <br />
                <button onClick={plusStateCountButtonHandler}>state 증가</button>
            </div>
            <div style={style}>
                ref 영역입니다. {countRef.current} <br />
                <button onClick={plusRefCountButtonHandler}>ref 증가</button>
            </div>
            <div>
                아이디:{' '}
                <input
                    type="text"
                    ref={idRef}
                    value={id}
                    onChange={(event) => {
                        setId(event.target.value);
                    }}
                />
                비밀번호: <input type="password" ref={pwRef} />
            </div>
            <GrandFather />
            <h3>카운터 예제입니다</h3>
            <p>현재 카운트: {count1}</p>
            <button onClick={onPlusButtonClickHandler}>+</button>
            <button onClick={onMinusButtonClickHandler}>-</button>
            <div
                style={{
                    display: 'flex',
                    marginTop: '10px',
                }}
            >
                <Box1 initCount={initCount} />
                <Box2 />
                <Box3 />
            </div>
            {/* [1-9] 최적화: useMemo
            heavy work: 엄청 무거운 작업을 만들어 보자 */}
            <nav
                style={{
                    backgroundColor: 'yellow',
                    marginBottom: '30px;',
                }}
            >
                네이게이션 바
            </nav>
            <HeavyComponent />
            <footer
                style={{
                    backgroundColor: 'green',
                    marginBottom: '30px;',
                }}
            >
                푸터 영역
            </footer>
        </>
    );
}

export default App;

 

 

 

6. 금일 소감

휴.. 이제 React는 어느 정도 복습한 것 같다. 아직 심화 과정 절반 정도를 더 들어야 하긴 하지만 일단은 TypeScript 남은 부분 완강한 뒤에 과제 하면서 들어야겠다. 이번 주까지, 그리고 다음 주까지 해서 내 부족한 부분을 모두 채우고 그 이상으로 코드 작성하고 발전하기 위해선 아직 엄청 부족하다. 그래도 매일 하나하나씩 잘해나가고 있다고 생각한다.

 

내일은 TypeScript 개인 과제 시작하고, React 심화 과정 완강하고 React Query 특강 2개까지 모두 다 들어야겠다. 파이팅 파이팅!!!

 

728x90