将输入内容完全匹配的建议放在顶部的类型提前排序

11
我正在使用 Twitter typeahead.js 0.10.5 作为建议引擎。它工作得很好,只有一个问题,我无法按照我想要的方式对建议列表进行排序。
例如:

我正在使用 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"... 当输入"he"时,应该是"he needs","all he needs","all I need"等。
我知道Bloodhound有一个排序选项,但我不知道如何在这种特定情况下使用它。
2个回答

13

你希望得到类似这样的东西。这将把完全匹配项移动到顶部。你需要继续修改排序代码以处理字符串大小写,空格和如何处理非完美但接近匹配项。这应该能为你提供起点。

        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"是什么。 - Carey Estes
a和b之间唯一的区别是,b是数组中紧随a后面的下一个对象。 - NoDiced

11

要将所有匹配项按照与输入的接近程度排序,您可以使用abLevenshtein距离。我刚刚使用fast-levenshtein实现了这一点,它运行得非常好。

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

一种优雅的解决方案,比已接受的答案快得多。 - eYe
“sorter” 是 typeahead 中的一个选项吗?我应该在哪里添加您的代码片段? - medley56

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接