【问题标题】:Sort typeahead suggestions with the exact input at top使用顶部的确切输入对预先输入的建议进行排序
【发布时间】:2015-02-26 13:08:03
【问题描述】:

我使用 Twitter typeahead.js 0.10.5 作为建议引擎。效果很好,除了一个例外,我无法按照我想要的方式对建议列表进行排序。

举个例子:

            var data =[{"id":1,"value":"no need"},
                        {"id":2,"value":"there is no need"},
                        {"id":3,"value":"in the need of"},
                        {"id":4,"value":"all I need"},
                        {"id":5,"value":"need"},
                        {"id":6,"value":"needs"},
                        {"id":7,"value":"all he needs"},
                        {"id":8,"value":"he needs"},
                        {"id":9,"value":"they need"},
                        {"id":10,"value":"you need"}]

            var suggestion = new Bloodhound({
                datumTokenizer: Bloodhound.tokenizers.obj.whitespace('value'),
                queryTokenizer: Bloodhound.tokenizers.whitespace,
                local: data,
                limit: 20
              });

              suggestion.initialize();

              $('.typeahead').typeahead({
                hint: true,
                autoselect: true,
                highlight: true,
                minLength: 1
              },
              {
                name: 'suggestion',
                displayKey: 'value',
                source: suggestion.ttAdapter(),
                templates: {
                empty: [
                  '<div class="empty-message">',
                  'no suggestion in this map',
                  '</div>'
                ].join('\n'),
                suggestion: Handlebars.compile('<p><span class="suggestion-text">{{value}}</span></p>')
              }

当我输入“need”时,我确实得到了按数组中位置排序的建议,但我希望它按输入排序,这意味着顺序应该是“need”、“needs”、“all I need”。 .. 输入“他”时,应该是“他需要”、“他需要的一切”、“我需要的一切”等。

我知道 Bloodhound 有一个分类器选项,但我不知道如何在这种特殊情况下使用它。

【问题讨论】:

    标签: sorting typeahead.js bloodhound


    【解决方案1】:

    你想要一些类似的东西。这会将完全匹配移动到顶部。您将需要继续修改排序器代码以处理字符串大小写、空格以及您希望如何处理非完美但接近的匹配项。这应该可以帮助您开始。

            var suggestion = new Bloodhound({
                datumTokenizer: Bloodhound.tokenizers.obj.whitespace('value'),
                queryTokenizer: Bloodhound.tokenizers.whitespace,
                local: data,
                limit: 20,
                sorter:function(a, b) { 
    
                         //get input text
                     var InputString=   $(Selector).val();
    
                         //move exact matches to top
                     if(InputString==a.value){ return -1;}
                     if(InputString==b.value){return 1;}
    
                          //close match without case matching
                     if(InputString.toLowerCase() ==a.value.toLowerCase()){ return -1;}
                     if(InputString.toLowerCase()==b.value.toLowerCase()){return 1;} 
    
                     if( (InputString!=a.value) && (InputString!=b.value)){
    
                          if (a.value < b.value) {
                             return -1;
                          }
                          else if (a.value > b.value) {
                             return 1;
                          }
                          else return 0;
                     }
                  },
              });
    

    【讨论】:

    • 谁能解释传递给函数 (a, b) 的两个值?我运行了一个控制台日志,“a”似乎是 JSON 对象,但我不知道“b”是什么。
    • a 和 b 的唯一区别是 b 将是数组中的下一个对象(直接在 a 之后)
    【解决方案2】:

    要按与输入的接近程度对所有匹配项进行排序,您可以采用abLevenshtein distance。我刚刚使用fast-levenshtein 实现了这一点,它工作得很好。

            sorter: function(a, b) {
                var input_string = $(selector).val();
                return levenshtein.get(a.key, input_string) - levenshtein.get(b.key, input_string);
            }
    

    【讨论】:

    • 一个优雅的解决方案,速度比公认的答案快。
    • sorter 是预先输入的选项吗?我应该在哪里添加你的 sn-p?
    猜你喜欢
    • 2023-04-08
    • 1970-01-01
    • 1970-01-01
    • 2020-07-09
    • 1970-01-01
    • 2017-01-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多