通过属性高效缓存搜索巨大的对象

时间:2017-05-18 20:50:02

标签: javascript filter react-native autocomplete

我有一个巨大的js对象,可以容纳所有用户帖子,

某些用户可能在此对象中有超过300个帖子,因此我想实现搜索机制

示例:

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

ps。:我正在使用ES6,它是一个反应原生的项目。

一种简单的搜索方法可以是:

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

现在这个功能很好,问题是我应该多久触发一次搜索? 并且让用户输入“var”这将触发搜索,然后他添加一个新的字母“varc”,这样就不会过滤主对象购买而是搜索来自“var”的已经很短的列表。

是否存在一种优化此类自动完成/搜索功能的解决方案?

1 个答案:

答案 0 :(得分:1)

更新

您可以将主列表设置为list州属性,然后重复搜索,直到您没有一些关键字在组件中不包含您当前的关键字。

基本上,这个版本:



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
&#13;
&#13;
&#13;