Momen Zalabany
Momen Zalabany

Reputation: 9007

Searching huge object by property performant caching

i have a huge js object which hold all user posts,

some users might have more than 300+ post in this object, so i want to implement a search mechanism

example:

{
 postById:{
   1:{ id:1, title:'varchar 250 string' },
   2:{ id:2, title:'varchar 250 string' },
   ...etc for 300+ items
 }
}

ps.: i' using ES6, its a react-native project.

a simple approach for search can be:

_handlSearch(keyword){
  const key= keyword.toLowerCase();
  return Object.keys(postById).filter(id=>posts[id].title.indexOf(key)>-1)
               .map(id=>postById[id])
}

now this function is fine, by question is how often should i trigger search ? and lets say user type "var" this will trigger search, then he add a new letter "varc" so it would make sence to not filter the master object buy rather search the already short list which came from "var".

is there a already existent solution that optimize such autocomplete/search functionality ?

Upvotes: 0

Views: 37

Answers (1)

lunochkin
lunochkin

Reputation: 784

Updated.

You can set master list as list state property and then repeatedly search in it until you don't have some keyword which doesn't contain your current keyword in component.

Basically, this version:

import React, { Component } from 'react';

class ShortList extends Component {

  constructor(props){
      super(props);
      this.state = {list:props.master,keyword:String(props.keyword||'').toLowerCase()};
      this._hadleSearchMaster = this._hadleSearchMaster.bind(this)
      this.trigger = this.trigger.bind(this)
      this.extract = typeof props.getValue==='function' ? props.getValue : f=>String(f);
      this.minLength = props.minLength||3;
      this.debounce = 0;
  }
  _hadleSearchMaster(){
    const list = Object.keys(this.props.master).map(id=>this.extract(this.props.master[id]).indexOf(this.state.keyword)>-1);
    console.log('searched master and returned'+this.state.keyword,Object.keys(this.props.master),list);
    this.setState({list});
  }
  trigger(){
    clearTimeout(this.debounce);
    this.debounce = setTimeout(this._hadleSearchMaster, 200);
  }
  componentWillReceiveProps(props){
    this.extract = typeof props.getValue==='function' ? props.getValue : f=>String(f);
    if(props.getValue!==this.props.getValue)this.extract = props.getValue;
    if(props.minLength!==this.props.minLength)this.minLength = props.getValue;

    if(!props.keyword || props.keyword.length < this.minLength)return;
    if(props.keyword===this.props.keyword)return;
    
    const keyword = String(props.keyword||'').toLowerCase();
    const stateToSet = {keyword};
    if (keyword.substr(0, this.state.keyword.length) !== this.state.keyword) {
      stateToSet.list = props.master;      
    }
    this.setState(stateToSet,
                  this.trigger)

  }
  render() {
    return this.props.render(this.state.list);
  }
}
//<Shortlist master={{}} style={{}} getValue={f=>f.title.toLowerCase()} keyword='search' render={idList=>null} minLength={3} />
export default ShortList

Upvotes: 1

Related Questions