99Build a lightweight client-side search index for 10,000 records
mediumAbout 45 minutesCodingsearchinverted-indexalgorithmsperformance
Problem
Filtering 10,000 records with includes on every keystroke is slow and gives poor results. Build a small search engine:
tokenize(text): lower-case, remove accents (Cafébecomescafe), and split on anything that is not a letter or digit."Café-Crème, 2024!"gives["cafe", "creme", "2024"].createSearchIndex(records, { fields, idField = "id", weights = {} })builds an inverted index (token → records containing it) and returns{ search(query, { limit = 10 }) }.
search rules:
- Every query token must match (AND).
- The last token also matches as a prefix, so results appear while the user is still typing (
"reac"findsReact). - Score = the sum of field weights (default 1) for every occurrence of a matching token; a prefix match counts half.
- Return the matching records sorted by score (higher first), ties in original order, at most
limit. - An empty query returns
[].
It must build an index of 10,000 records and answer 1,000 queries in well under a second.
Try it yourself
Write your solution, run it, then submit to check it against the tests.
App.jsxReact + DOM
Step-by-step
The same tokenize runs on the records and the query, so "Café" in data and "cafe" in a query produce the same token. normalize("NFD") splits "é" into "e" plus a combining accent, and /\p{M}/gu removes the accent. Then split on /[^\p{L}\p{N}]+/u.
Unlock the full solution
What's inside
- Step-by-step
- Approach
- Solution
- Complexity
- Edge cases
- Follow-up questions
- Tests
Includes 2 code listings, 5 edge cases, 4 follow-up questions.
One-time payment by UPI, card or net banking. Launch price.