【问题标题】:Optimize trie implementation to search autocomplete优化 trie 实现以搜索自动完成
【发布时间】:2016-11-30 21:52:59
【问题描述】:

我有一个项目让用户在 json 文件中查找国家/地区, 我已经改变了我的 json 文件的结构:

{
"AE": {"name": "United arab emirates","alternate": "UAE"},
"GB": {"name": "United kingdom","alternate": "Great Britain England","weight": "2.5"},
"US": {"name": "United states","alternate": "USA United States of America","weight": "3.5"},
.........
}

到这个结构:

var countries = {
"name": "United arab emirates","alternate": "UAE",
"name": "United kingdom","alternate": "Great Britain England","weight": "2.5",
"name": "United states","alternate": "USA United States of America","weight": "3.5",
.........
}

但我不知道如何编辑 js 代码以使用 json 新结构,

这是我的代码: 国家.js:

(function () {
  'use strict';
  // var log = console.log.bind(console);
  // No timing in IE (sucker)
  if(!console.time) {
    console.time = console.timeEnd = function() {};
  }
  var countries, index;
  function indexData() {
    index = new T.Index({
      'name' :'countries',
      'indexSubstring': false,
      'intersectResults': true
    });
    console.time('loading');
    index.load(function(err) {
      if(err) {
        console.time('indexing');
        Object.keys(countries).forEach(function(id) {
          var country = countries[id];
          var toIndex = [country.name , country.alternate].join(' ');
          index.add(id, toIndex, country.weight || 1);
        });
        console.timeEnd('indexing');
        console.time('saving');
        index.save(function() {
          console.timeEnd('saving');
        });
      }
      else {
        // Already loaded
        window.index = index;
        console.timeEnd('loading');
      }
    });
  }
  var request = new XMLHttpRequest();
  request.onreadystatechange = function() {
    if(request.readyState === 4) {
      // Break the cyclic reference
      request.onreadystatechange = null;
      if (typeof request.responseText === "string") {
        try {
          countries = JSON.parse(request.responseText);
        } catch(e) {
          // do something
        }
        // Index, if data was loaded
        if(countries) {
          indexData();
        }
      }
    }
  };
  request.open('get', 'data/countries.json', true);
  request.send();
  var search = document.getElementById('search');
  var results = document.getElementById('results');
  var lastVal;
  function lookup() {
    var query = search.value;
    if(lastVal === query) {
      return;
    }
    // Time the lookup
    console.time('lookup: ' + query);
    var ids = index.search(query);
    console.timeEnd('lookup: ' + query);
    // render the list
    results.innerHTML = ids.map(function(id) {
      var country = countries[id];
      return '<li rel="' + id + '">' + country.name + '</li>';
    }).join('');
    lastVal = query;
  }
  search.addEventListener('keyup', lookup, false);
}).call(null);

countries.html:

<html>
<head>
  <title>Trie.js</title>
  <link rel="stylesheet" type="text/css" href="style.css">
  <!--- trie-structure implementation ---->
  <script type="text/javascript" src="https://rawgit.com/wunderlist/trie.js/master/dist/trie.js"></script>
</head>
<body>
  <label>Type in a country name</label>
  <input id="search" autocomplete="off" autofocus="autofocus" />
  <ul id="results" />
  <script type="text/javascript" src="js/countries.js"></script>
</body>
</html>

更新: 我还试图将结果限制为 5 条建议。但我也卡住了。

请帮忙谢谢。

【问题讨论】:

  • 您的新结构不再是有效的 JSON。您的意思是使用数组吗?
  • @Bergi 是的。

标签: javascript json trie


【解决方案1】:

我不明白您想对搜索进行哪些更改?它使用 triejs 库构建树结构,基于您的 json 文件,并使用 triejs 的搜索方法根据输入查找结果。它看起来像它的作品。

要限制输出,您可以像这样稍微更改地图功能,例如:

results.innerHTML = ids.map(function(id, i) {
  var country = countries[id];
  if (i < 5) {
     return '<li rel="' + id + '">' + country.name + '</li>';
  }
 }).join('');

【讨论】:

  • 我想摆脱国家[id] 因为它在我的情况下没用@stee1rat
  • @EileenLorant 你的意思是你想摆脱 Trie.js 吗?如果是这样 - 您仍然需要获取有效的 json 并在 country.json 中删除 var countries = ,然后自己过滤结果。
猜你喜欢
  • 1970-01-01
  • 2013-02-17
  • 2018-12-07
  • 2014-06-30
  • 2023-03-06
  • 1970-01-01
  • 2012-06-08
  • 2015-07-05
  • 1970-01-01
相关资源
最近更新 更多