Array Object를 특정 key값 기준으로 그룹화 (reduce())

JJY·2024년 8월 9일

FRONT

목록 보기
7/11

🌟 Array Object를 특정 key값 기준으로 그룹화

export const dummy = [
  { fruit: "Apple", color: "Red" },
  { fruit: "Strawberry", color: "Red" },
  { fruit: "Cherry", color: "Red" },
  { fruit: "Banana", color: "Yellow" },
  { fruit: "Lemon", color: "Yellow" },
  { fruit: "Blueberry", color: "Blue" },
];

dummy의 fruit를 리스트로 출력하는데

Red
Apple
Strawberry
Cherry
Yellow
Banana
Lemon
Blue
Blueberry

이런식으로 color출력 후 fruit을 출력하도록 구현해야 한다.
처음 방식은 useState를 사용해서 color값이 바뀔 때 한번 출력해주는 식으로 구현하였는데 useState가 바뀌고 바로 사용해서 무한 렌더링 발생...
그래서 초기에 color에 따라서 미리 그룹화하면
Color 출력 -> 그룹화한 객체들 출력가능하다 !!

🌟 reduce(), Record

useEffect()로 초기 렌더링 시 dummy를 그룹화

interface Types {
  description: string;
  key: string;
  type: string;
}

const [data, setData] = useState<{ [key: string]: Types[] }>({});

  useEffect(() => {
    const dum: Record<string, Types[]> = dummy.reduce((acc, obj) => {
      if (!acc[obj.color]) {
        acc[obj.color] = [];
      }
      acc[obj.color].push(obj);
      return acc;
    }, {} as Record<string, Types[]>);

    setData(dum);
  }, []);

그룹화된 결과를 담을 acc와 현재 값인 obj
color에 따라 그룹화하므로 obj.color를 가져와서 acc에 있는지 확인하고
없으면 해당 color 빈배열 생성한다.
있으면 그 배열에 현재 obj를 집어넣는다.
미리 color를 타입을 지정해서 해도 되지만 color에 뭐가 있는지 모를 수 있고
다른 color를 가진 데이터가 추가 되는 경우에 유연하게 사용가능하도록 구현하고자 한다.

Record<Key, Value>
키가 Key타입이고 값이 Value 타입인 객체 타입을 생성함

useState에 저장하기 위해서 키가 string이고 값이 객체 타입이 필요하다
그래서 Record를 사용했다.

🌟 출력하기

<div className="search-area">
   {Object.keys(data).map((category) => (
        <div className="category" key={category}>
            <div>{category}</div>
            {data[category].map((text, index) => (
              <div key={index}>{text.fruit}</div>
            ))}
        </div>
     ))}
</div>

Object.keys() 로 객체의 키값들, color을 배열에 집어넣고
color를 우선 출력한다.
그 후 data를 가져와서 지금 키값이 가지고 있는 Value값을 map으로
하나씩 출력해주면 된다. 😀

🌟 결과

profile
안녕하세요 :)

0개의 댓글