FrontendPro

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é becomes cafe), 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" finds React).
  • 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.

All 150 answersOne payment, yours forever