02. JS 배열 메소드 정리

Gardener·2024년 3월 11일

NoColored

목록 보기
2/7

뜬금없이 Phaser 3 공부하다 말고 웬 Js입니까 라고 물어본다면, 할 말이 없다. 그것은 내가 공부를 하지 않고 GPT-4를 사용했기 때문이다. 코드리뷰에 떨어지며,, 반성하며 적어내는 나의 프로젝트 일지. 왜 JavaScript가 나왔냐.. 바로 지금은 공통 컴포넌트를 만들어내는 시간이기 때문이다.

좋다, Vanilla-extract-css에 대한 기본적인 이해는 한 상태다. 나는 styles로 찍어내려고 하는데, 갑자기 등장한 recipe. recipe로 찍어내려고 하니까, 따로 배열을 만들죠? 따로 배열을 빼라고요? 제가 왜요? 이유는 우리 FL이 객체화에 미친 사람이라는 것이다. 객체화 좋지, 좋은데 힘들잖아. 하지만 유연성과 확장성이 없긴 하다. 그리고 알면 좋다.

아래는 내가 작성한 코드이다.

import { style } from '@vanilla-extract/css';

import { vars } from '@/styles/vars.css.ts';

export type ColorMap = {
  [K in 'blue' | 'green' | 'navy' | 'red' | 'yellow' | 'pink' | 'gray300']: {
    backgroundColor: string;
    shadowColor: string;
  };
};

export type ColorStyles = {
  [K in keyof ColorMap]: ReturnType<typeof style>;
};

export const colorMap: ColorMap = {
  blue: {
    backgroundColor: vars.colors.blue,
    shadowColor: vars.colors.blueDark,
  },
  green: {
    backgroundColor: vars.colors.green,
    shadowColor: vars.colors.greenDark,
  },
  navy: {
    backgroundColor: vars.colors.navy,
    shadowColor: vars.colors.navyDark,
  },
  red: {
    backgroundColor: vars.colors.red,
    shadowColor: vars.colors.redDark,
  },
  yellow: {
    backgroundColor: vars.colors.yellow,
    shadowColor: vars.colors.yellowDark,
  },
  pink: {
    backgroundColor: vars.colors.pink,
    shadowColor: vars.colors.pinkDark,
  },
  gray300: {
    backgroundColor: vars.colors.gray300,
    shadowColor: vars.colors.gray500,
  },
};

export const createColorStyles = (colorsMap: ColorMap): ColorStyles => {
  return Object.entries(colorsMap).reduce<ColorStyles>(
    (styles, [colorKey, { backgroundColor, shadowColor }]) => {
      styles[colorKey as keyof ColorMap] = style({
        backgroundColor,
        boxShadow: `0 6px ${shadowColor}`,
        ':active': {
          top: '8px',
          boxShadow: `0 2px ${shadowColor}`,
        },
      });
      return styles;
    },
    {} as ColorStyles,
  );
};

대충 설명해주자면, ColorMap의 배열 키값의 상태에 따라, 그에 맞게 저장된 backgroundColor와 shadowColor가 같이 딸려나와 style에 바인딩 된다. vars와 styles는 추후 포스팅에서 작성하겠다.

그럼 돌고 돌아서 Object의 entries는 또 뭐고 reduce는 또 뭐에요?

reduce()

: 배열의 각 요소에 대해 주어진 리듀서 (reducer) 함수를 실행하고, 하나의 결과값을 반환한다.

사용법

array.reduce((accumulator, currentValue, currentIndex, array) => { /* 로직 */ }, initialValue)

const numbers = [1, 2, 3, 4];
const sum = numbers.reduce((acc, current) => acc + current, 0);
console.log(sum); // 출력: 10

entries()

: 배열의 각 인덱스에 대한 '[index, value]' 쌍을 포함하는 새로운 배열 객체를 반환한다.

const fruits = ['apple', 'banana', 'cherry'];
const iterator = fruits.entries();

for (let [index, fruit] of iterator) {
  console.log(index, fruit);
}
// 출력: 0 'apple'
// 출력: 1 'banana'
// 출력: 2 'cherry'

다른 메소드들도 더 알아보자.

map()

: 배열의 모든 요소에 대해 주어진 함수를 호출한 결과를 모아 새로운 배열을 반환

const numbers = [1, 2, 3, 4];
const doubled = numbers.map(x => x * 2);
console.log(doubled); // 출력: [2, 4, 6, 8]

filter()

: 주어진 함수의 테스트를 통과하는 모든 요소를 모아 새로운 배열을 반환

const numbers = [1, 2, 3, 4, 5];
const even = numbers.filter(x => x % 2 === 0);
console.log(even); // 출력: [2, 4]

find()

: 주어진 테스트 함수를 만족하는 배열의 첫 번째 요소의 값을 반환한다. 그런 요소가 없다면 undefined를 반환한다.

const numbers = [1, 2, 3, 4];
const firstEven = numbers.find(x => x % 2 === 0);
console.log(firstEven); // 출력: 2

forEach()

: 배열의 각 요소에 대해 주어진 함수를 실행합니다. 반환 값은 없음

const fruits = ['apple', 'banana', 'cherry'];
fruits.forEach((fruit, index) => {
  console.log(index, fruit);
});
// 출력: 0 'apple'
// 출력: 1 'banana'
// 출력: 2 'cherry'

여기서 끝내기는 아쉬워서 TypeScript 얘기 하나만 더 하고 가겠다.

[K in keyof ColorMap]: ReturnType<typeof style>;

이 부분이 개인적으로 조금 어려워서 공부함

keyof

: 객체 타입에 사용되며, 해당 객체 타입의 모든 키(속성 이름)를 문자열 또는 숫자 유니언으로 반환함.

interface Person {
  name: string;
  age: number;
}
type PersonKeys = keyof Person; // "name" | "age"

typeof

: 변수의 타입을 취하여, 그 타입을 사용하기 위해 사용함.

const person = {
  name: "Alice",
  age: 30,
};
type PersonType = typeof person;
// PersonType는 { name: string; age: number; } 타입이 됨.

멀고도 험한 javaScript, typeScript의 세계. 화요일의 나야 부탁해.

profile
영혼의 정원수

0개의 댓글