Map 자료구조로 속도 높이기

아이콘검색의 부분검색 요청 VoC를 해결하기 위해 로직을 변경했더니 검색속도가 늦어졌다.
구주애's avatar
Apr 07, 2024
Map 자료구조로 속도 높이기

유저는 backpack 또는 book bag을 입력했을 때에 가방 관련 아이콘이 나오길 원했으나 가방 아이콘은 정확히 ‘bag’을 입력할 때에만 나옴 (현재는 book bag과 같이 입력한 경우 book이 우선검색되므로 기대한 bag의 결과를 얻을 수 없음)

→ bag이라는 단어가 내가 입력한 단어 안에서, 어느 위치에라도 포함되어있으면 결과로 나오길 원함

여기서 해결해줘야 할 검색의 정도(?)

1️⃣

  • 검색어: Apple juice → 결과: apple, juice가 포함되는 tag를 가진 모든 아이콘 (lime juice, apple pencil)

  • 검색어: 커피 머신 → 결과: 커피, 머신 포함되는 tag를 가진 모든 아이콘 (커피 그라인더, 머신러닝)

2️⃣

  • 검색어: Apple juice → 결과: apple, juice에 해당되는 아이콘

  • 검색어: 커피 머신 → 결과: 커피, 머신에 해당되는 아이콘

1번은 검색시간도 급격히 늘어날 가능성 있으며 스프린트 남은 가용시간 안에 가능할지 미지수이므로 2번으로 진행

현재 검색방식: 정규표현식 match

const textWithoutSynctaxError = searchingText.replace(/\[/g, '');
const search = new RegExp(textWithoutSynctaxError, 'i');
...
    
taggedIconList.map((taggedIcon: any) => {
  if (taggedIcon.tags.match(search)) {
    ...
  }
});

수정 후

const iconMap = new Map(); // 아이콘을 태그에 따라 그룹화할 Map 생성

// 아이콘을 태그에 따라 그룹화하여 Map에 저장
taggedIconList.forEach(icon => {
  const tags = icon.tags.split(',').map(tag => tag.trim().toLowerCase()); // 태그를 소문자로 변환하여 분리하고 공백 제거
  tags.forEach(tag => {
    if (!iconMap.has(tag)) {
      iconMap.set(tag, new Set()); // 새로운 태그인 경우 Set을 생성하여 맵에 추가
    }
    iconMap.get(tag).add(icon.image); // 해당 태그의 Set에 아이콘 추가
  });
});

// 검색어에 해당하는 아이콘들을 모으기
const searchingTextArray = searchingText
  .split(/(\s+)/)
  .filter(e => e.trim().length > 0)
  .map(text => text.toLowerCase()); // 검색어를 소문자로 변환

const result = new Set(); // 중복 제거를 위해 Set 사용

searchingTextArray.forEach(text => {
  iconMap.forEach((iconSet, tag) => {
    if (tag.includes(text)) {
      iconSet.forEach(icon => result.add(icon)); // 검색어가 태그에 포함되면 결과에 해당 아이콘 추가
    }
  });
});

return Array.from(result);
Share article

KooLog