feat(games): improve search for games

This commit is contained in:
en 2025-02-03 19:53:48 +01:00
parent 474a1b0f0a
commit 93a7419006
2 changed files with 67 additions and 2 deletions

View File

@ -36,6 +36,7 @@ import {
DEFAULT_FILTER_OPTIONS,
extractModData,
isModDataComplete,
memoizedNormalizeSearchString,
scrollIntoView
} from 'utils'
import { useCuratedSet } from 'hooks/useCuratedSet'
@ -502,10 +503,12 @@ const GamesResult = ({ searchTerm }: GamesResultProps) => {
const filteredGames = useMemo(() => {
if (searchTerm === '') return []
const lowerCaseSearchTerm = searchTerm.toLowerCase()
const normalizedSearchTerm = memoizedNormalizeSearchString(searchTerm)
return games.filter((game) =>
game['Game Name'].toLowerCase().includes(lowerCaseSearchTerm)
memoizedNormalizeSearchString(game['Game Name']).includes(
normalizedSearchTerm
)
)
}, [searchTerm, games])

View File

@ -198,3 +198,65 @@ export function adjustTextareaHeight(textarea: HTMLTextAreaElement) {
textarea.style.height = 'auto'
textarea.style.height = `${textarea.scrollHeight}px`
}
// Normalizing search terms
const removeAccents = (str: string): string => {
return str.normalize('NFD').replace(/[\u0300-\u036f]/g, '')
}
const removeSpecialCharacters = (str: string): string => {
return str.replace(/[.,/#!$%^&*;:{}=\-_`~()&\s]/g, '')
}
// Replace Roman numerals with their Arabic counterparts
const ROMAN_TO_ARABIC_MAP: { [key: string]: string } = {
i: '1',
ii: '2',
iii: '3',
iv: '4',
v: '5',
vi: '6',
vii: '7',
viii: '8',
ix: '9',
x: '10',
xi: '11',
xii: '12',
xiii: '13',
xiv: '14',
xv: '15',
xvi: '16',
xvii: '17',
xviii: '18',
xix: '19',
xx: '20'
}
const romanRegex = new RegExp(
`\\b(${Object.keys(ROMAN_TO_ARABIC_MAP).join('|')})\\b`,
'g'
)
export const normalizeSearchString = (str: string): string => {
str = str.toLowerCase()
str = removeAccents(str)
str = removeSpecialCharacters(str)
return str.replace(romanRegex, (match) => ROMAN_TO_ARABIC_MAP[match])
}
// Memoization function to cache normalized results
const memoizeNormalize = (func: (str: string) => string) => {
const cache: { [key: string]: string } = {}
return (str: string): string => {
if (cache[str] !== undefined) {
return cache[str]
}
const result = func(str)
cache[str] = result
return result
}
}
export const memoizedNormalizeSearchString = memoizeNormalize(
normalizeSearchString
)