본문 바로가기
부트캠프/프로젝트 회고록

다중 필터 (zero-gg 회고록)

by BTSBRINGMEHERE 2023. 1. 19.

다중 필터

프로젝트를 진행하던 중 필터 작업을 시작했습니다. 

별 생각없이 map을 이용하여 if문을 쥐어주고 &&를 쓰면 되겠지? 라는 생각을 했지만 해당 필터에서는 조건이 단 2개만 허용되는 필터였습니다. 제가 원하는 조건은 총 7개가 필요했으며.. 다양한 블로그와 문서를 찾아내면서 필터를 마무리 할 수 있었습니다.

 

첫 번째 map

map을 이용하여 해당 조건에 대입하는 것이였습니다.

//lolInfo 해당 객체가 들어간 state

const [selectValue, setSelectValue] =useState<FilterType>({
  queue: "",
  tier: "",
  position: "",
})

const filterArr = lolInfo.map((item: DuoType, idx: number) => {
  if(item.queue === selectValue.queue){
    return arr.push(item)
    if(item.position === selectValue.position){
      return arr.push(item)
      .
      .
      .
   }
   setSelectValue(filterArr)
 }

처음에는 이런식으로 나열을 했지만 생각해보면 효율적이지 않은 코드 그리고 조건이 달라질수도 있음에 따른 변수등에 의해 좋지 않은 코드가 만들어져 버렸습니다. 또한 or 연산자 "||" 을 이용해서 코드를 줄이고자 했지만 조건이 2개 이상이 되버리면 모두 검색이 되버렸습니다..

 

두 번째 filter

필터자체가 필터링을 위해 만든 것이기 때문에 filter chaning을 통해 작업을 하려했지만 사실 chaning과정이 좋지 않았습니다.

const filterArr = lolInfo.filter((item: DuoType) => item.queue === selectValue.queue)
                         .filter((item: DuoType) => item.position === selectValue.position)
                         .filter((item: DuoType) => item.tier === selectValue.tier)

이런식으로 간략하게 만들 수 있었지만 만약에 새로운 객체가 생성되거나 조건에 바뀌면 이러한 과정을 다시 반복해야했으며 객체가 많으면 많아질수록 필요없는 렌더링이 일어나고 리스트 전체를 순회하는 걸 반복하는 양상이었습니다.

 

마지막 reduce

사실 reduce는 이해도 안되고 어떻게 사용할지 엄두도 안나서 진행을 하지 않으려고 했지만 여러 블로그와 문서를 깃허브 이슈탭에 올리고 map과 if문을 이용하거나 reduce문을 이용해서 다중 필터 작업에 대해서 고민을 했습니다.

 

하지만 멘토님이 reduce의 방향이 좋다고 해서 만들어 봤습니다. filter와 달리 순회하는 것이 아니라 데이터를 누적시키기 때문에 한방이라는 표현을 하셨습니다.

 

const [lolInfo, setLolInfo] = useState<any[]>([]); // firebase를 통해 실제 값
const [lolInfoFilterList, setLolInfoFilterList] = useState<any[]>([]); // 필터 값
const [selectValue, setSelectValue] = useState<FilterType>({
  queue: '',
  tier: '',
  position: '',
});

const FilterDuoData = () => {
  const selectPosition = selectValue.position;
  const selectQueue = selectValue.queue;
  const selectTier = selectValue.tier;

  if (selectPosition && selectQueue && selectTier === null) {
    setLolInfoFilterList(lolInfo);
  } else {
    const filteredList = lolInfo.reduce(
      (acc, cur) => {
        const positionCondition = selectPosition ? cur.position === selectPosition : true;
        const queueCondition = selectQueue ? cur.queue === selectQueue : true;
        const tierCondition = selectTier ? cur.tier === selectTier : true
        // 해당 값이 존재하지 않으면 true로 반환
        if (positionCondition && queueCondition && tierCondition) {
          acc.push(cur);
        }

        return acc;
      },
      [selectValue],
    );
    filteredList.splice(0, 1); // reduce는 빈 객체의 값이 들어가서 잘라냈습니다
    setLolInfoFilterList(filteredList);
  }
};

const onFilterChange = useCallback(
  (e: ChangeEvent<HTMLInputElement>) => {
    const {
      currentTarget: { value, name },
    } = e;
    setSelectValue({ ...selectValue, [name]: value });
  },
  [selectValue],
);

useEffect(() => {
  getDuoData();
}, []);

useEffect(() => {
  FilterDuoData();
}, [lolInfo, selectValue, setSelectValue]);

완성된 코드입니다. reduce로 한방에 해결하니 다양한 조건에서도 필요한 조건에만 부합하게 나오고 filter보다 빠르게 처리할 수 있었습니다.

 

정리

다중 필터(multiple-filter)라는 것을 처음 접해봤습니다. 대략적인 하나의 조건으로 삼중연산자를 사용해서 필터를 했지만 해당 조건이 늘어나면

해당 그림과 같은 조건이 필요하게 되므로 if문을 늘리는건 솔직하게 비효율적인 코드였습니다.

블로그를 뒤지다가 찾게되었지만 솔직하게 큰 도움이 되었습니다.

 

참고

https://velog.io/@parfaite73/Project1-7-%EA%B2%80%EC%83%89%ED%95%84%ED%84%B0-%EC%97%AC%EB%9F%AC%EA%B0%9C-%EC%A1%B0%EA%B1%B4%EC%9C%BC%EB%A1%9C-%EA%B2%80%EC%83%89%ED%95%98%EA%B8%B0-feat.-react-datepicker-Debounce

 

||Project1|| #7 검색필터: 여러개 조건으로 검색하기 (feat. Debounce, 날짜비교)

이번 프로젝트에서 가장 어려웠던 부분을 꼽으라면, 이 자리에 눕겠다.

velog.io

https://choonse.com/2022/04/25/1075/

 

map, reduce, filter 서로 대체가 가능할까 (javascript) - WORLD IS WIDE

자바스크립트에서 배열의 요소에 접근하는 대표 메서드인 map, reduce, filter는 개발자라면 필수적으로 그리고 좀 더 상세히 알고 가면 좋을 것 같습니다. 각 메서드 구조와 서로 교환하여 사용이

choonse.com

 

'부트캠프 > 프로젝트 회고록' 카테고리의 다른 글

PWA (zero-gg 회고록)  (0) 2023.02.07
firebase (zero-gg 회고록)  (0) 2023.01.25
React 첫 Back/Front 프로젝트 어려웠던 점  (2) 2022.09.23