Skip to main content
Tweeted twitter.com/StackCodeReview/status/1248219231029792774
added 170 characters in body
Source Link
Joji
  • 325
  • 2
  • 14

I have a typeahead widget to get the state or city's population according to what the user types

Instead of issuing a GET request every time the user is done typing, the way this typeahead widget works is fetch data beforehand and store it in memory and every time user types, we are iterating through the data to retrieve the stuff that we need.

The live demo is here: https://codesandbox.io/s/saveddatatypeahead-lcyfg?file=/src/index.js

So the data is fetched like this


const data = [];

fetch(endpoint)
  .then(res => res.json())
  .then(result => {
    data.push(...result);
  });

and we listen for the input event on the input field, the timeId is for debouncing the searching, we don't want to search too frequently

searchInput.addEventListener("input", e => {
  if (e.target.value.length > 2) {
    if (timeId) {
      clearTimeout(timeId);
    }
    timeId = setTimeout(() => {
      displayMatches(e.target.value);
    }, 500);
  }
});

and the search is performed here

function findMatches(regex, data) {
  // the time complexity is 
  // O(M x K)
  // M is the length of a city or state
  // K is the keyword to match
  // e.g. M - 'New York' K - 'yo'
  return data.filter(
    place => place.city.match(regex) || place.state.match(regex)
  );
}

Here the regex is constructed based on what the user typed const regex = new RegExp(text, "ig");

So for now it seems to me that the time complexity for the searching here is O(N x M x K) N is the number of entries in the data array, M is the average length of every city or state's name, and K is the keyword the user typed.

So my question is, is there a way to make the search more efficient? For now I have done two things to improve the efficiency.

1.if what the user types is less than 3 characters, we don't perform the search

2.debounce the search and only fire it when the user is done typing

Right the amount of data is not huge but I can see that it doesn't scale well with this naive implementation of search. Maybe building a trie can help? I am not sure.

Also any other suggestions and critiques about this widget are highly welcomed

I have a typeahead widget to get the state or city's population according to what the user types

Instead of issuing a GET request every time the user is done typing, the way this typeahead widget works is fetch data beforehand and store it in memory and every time user types, we are iterating through the data to retrieve the stuff that we need.

The live demo is here: https://codesandbox.io/s/saveddatatypeahead-lcyfg?file=/src/index.js

So the data is fetched like this


const data = [];

fetch(endpoint)
  .then(res => res.json())
  .then(result => {
    data.push(...result);
  });

and we listen for the input event on the input field, the timeId is for debouncing the searching, we don't want to search too frequently

searchInput.addEventListener("input", e => {
  if (e.target.value.length > 2) {
    if (timeId) {
      clearTimeout(timeId);
    }
    timeId = setTimeout(() => {
      displayMatches(e.target.value);
    }, 500);
  }
});

and the search is performed here

function findMatches(regex, data) {
  // the time complexity is 
  // O(M x K)
  // M is the length of a city or state
  // K is the keyword to match
  // e.g. M - 'New York' K - 'yo'
  return data.filter(
    place => place.city.match(regex) || place.state.match(regex)
  );
}

Here the regex is constructed based on what the user typed const regex = new RegExp(text, "ig");

So for now it seems to me that the time complexity for the searching here is O(N x M x K) N is the number of entries in the data array, M is the average length of every city or state's name, and K is the keyword the user typed.

So my question is, is there a way to make the search more efficient? For now I have done two things to improve the efficiency.

1.if what the user types is less than 3 characters, we don't perform the search

2.debounce the search and only fire it when the user is done typing

Also any other suggestions and critiques about this widget are highly welcomed

I have a typeahead widget to get the state or city's population according to what the user types

Instead of issuing a GET request every time the user is done typing, the way this typeahead widget works is fetch data beforehand and store it in memory and every time user types, we are iterating through the data to retrieve the stuff that we need.

The live demo is here: https://codesandbox.io/s/saveddatatypeahead-lcyfg?file=/src/index.js

So the data is fetched like this


const data = [];

fetch(endpoint)
  .then(res => res.json())
  .then(result => {
    data.push(...result);
  });

and we listen for the input event on the input field, the timeId is for debouncing the searching, we don't want to search too frequently

searchInput.addEventListener("input", e => {
  if (e.target.value.length > 2) {
    if (timeId) {
      clearTimeout(timeId);
    }
    timeId = setTimeout(() => {
      displayMatches(e.target.value);
    }, 500);
  }
});

and the search is performed here

function findMatches(regex, data) {
  // the time complexity is 
  // O(M x K)
  // M is the length of a city or state
  // K is the keyword to match
  // e.g. M - 'New York' K - 'yo'
  return data.filter(
    place => place.city.match(regex) || place.state.match(regex)
  );
}

Here the regex is constructed based on what the user typed const regex = new RegExp(text, "ig");

So for now it seems to me that the time complexity for the searching here is O(N x M x K) N is the number of entries in the data array, M is the average length of every city or state's name, and K is the keyword the user typed.

So my question is, is there a way to make the search more efficient? For now I have done two things to improve the efficiency.

1.if what the user types is less than 3 characters, we don't perform the search

2.debounce the search and only fire it when the user is done typing

Right the amount of data is not huge but I can see that it doesn't scale well with this naive implementation of search. Maybe building a trie can help? I am not sure.

Also any other suggestions and critiques about this widget are highly welcomed

Source Link
Joji
  • 325
  • 2
  • 14

How do I make the search in the typeahead widget more efficient

I have a typeahead widget to get the state or city's population according to what the user types

Instead of issuing a GET request every time the user is done typing, the way this typeahead widget works is fetch data beforehand and store it in memory and every time user types, we are iterating through the data to retrieve the stuff that we need.

The live demo is here: https://codesandbox.io/s/saveddatatypeahead-lcyfg?file=/src/index.js

So the data is fetched like this


const data = [];

fetch(endpoint)
  .then(res => res.json())
  .then(result => {
    data.push(...result);
  });

and we listen for the input event on the input field, the timeId is for debouncing the searching, we don't want to search too frequently

searchInput.addEventListener("input", e => {
  if (e.target.value.length > 2) {
    if (timeId) {
      clearTimeout(timeId);
    }
    timeId = setTimeout(() => {
      displayMatches(e.target.value);
    }, 500);
  }
});

and the search is performed here

function findMatches(regex, data) {
  // the time complexity is 
  // O(M x K)
  // M is the length of a city or state
  // K is the keyword to match
  // e.g. M - 'New York' K - 'yo'
  return data.filter(
    place => place.city.match(regex) || place.state.match(regex)
  );
}

Here the regex is constructed based on what the user typed const regex = new RegExp(text, "ig");

So for now it seems to me that the time complexity for the searching here is O(N x M x K) N is the number of entries in the data array, M is the average length of every city or state's name, and K is the keyword the user typed.

So my question is, is there a way to make the search more efficient? For now I have done two things to improve the efficiency.

1.if what the user types is less than 3 characters, we don't perform the search

2.debounce the search and only fire it when the user is done typing

Also any other suggestions and critiques about this widget are highly welcomed