如何提高我的backbone.js搜索功能?

时间:2014-07-20 04:48:23

标签: javascript regex function search backbone.js

我有一个搜索功能,作为我正在编写的骨干应用程序的一部分。我想帮助扩展它。理想情况下,我希望能够

  1. 在我的模型中搜索多个类别
  2. 不一定要这么完全匹配(可能使用RegEx?)
  3. 这是我的代码:

    search: function(e) {
               var search = this.$('.search').val();  //pulling in from the search bar
               results = namesCollection.filter(function(item) { return item.get('First_Name') == (search);}); //returns a filtered collection that matches (exactly) the search results
               filteredCollection.reset(results); //this just resets the current view
    }
    

    代码有效,但现在它只返回First_Name上完全匹配的结果。有没有办法让它匹配First_Name和Last_Name?此外,我正试图找到一种方法让它返回不完整的搜索。因此,在搜索栏中输入'Joh'将返回John和Johanna的First_Name。

    以下是我的数据的样子(当然简化):

    var data = [
                {
                 "First_Name": "John",
                 "Last_Name": Smith
                },
                {
                 "First_Name": "Johanna",
                 "Last_Name": "Greene"
                }
              ];
    

    namesCollection是指我数据集中所有名称的骨干集合。谢谢!

3 个答案:

答案 0 :(得分:1)

至于搜索名字和姓氏为什么不在你的过滤结果上运行另一个过滤器?您可以按空格分割搜索。

results = namesCollection.filter(function(item) { return item.get('First_Name') == (search.split(' ')[0]);});
if(search.split(' ').length > 1){
    results = namesCollection.filter(function(item) { return item.get('Last_Name') == (search.split(' ')[1]);});
}

至于找到一个可能与错误单词一起使用的类似字符串,你可能需要像Levenshtein函数这样的函数,它允许你计算字符串之间的相似性。然后,您可以根据自己的阈值确定是否将其视为匹配项。 Here is a js library for it

如果你想要进行部分匹配,假设它们拼写正确,你可以先搜索完全匹配,如果找到一个匹配(假设第一个名称,这意味着分割后只有一个元素)。如果未找到完全匹配,请尝试与indexOf()进行部分匹配。如果你得到第一个名字的匹配,并且还有一个姓氏(意味着分割中有多个元素),那么尝试完全匹配姓氏。如果该姓氏匹配失败,则执行部分匹配搜索。

答案 1 :(得分:1)

我会利用lodash /下划线。让生活变得轻松。您可以解构为原生js,但我发现这更容易。

#!/usr/bin/env node

_ = require('lodash');

var search = 'john';

var data = [
    {
        "First_Name": "John",
        "Last_Name": "Smith"
    },
    {
        "First_Name": "Jessica",
        "Last_Name": "Greene"
    },
    {
        "First_Name": "Sam",
        "Last_Name": "Johnson"
    }
];

var re = new RegExp(search, 'i');

data = data.filter(function(model){
    var matched = false;

    _.each(_.values(model), function(val){  
        if ( re.test(val) ) {
            matched = true;
        }
    });

    return matched;
});

console.log(data);

输出:

[ { First_Name: 'John', Last_Name: 'Smith' },
  { First_Name: 'Sam', Last_Name: 'Johnson' } ]

要处理主干集合,您需要this.collection.filtermodel.attributes使用_.values(model.attributes, cb)。假设它是一个扁平的物体。

这当然会匹配对象中的任何值,我在节点中完成,但很容易在骨干/浏览器中运行。

答案 2 :(得分:0)

我对Backbone不太熟悉,但是如何将完全匹配更改为.indexOf或.contains?这样,它可以在您输入关键字时进行过滤,因此在键盘上您可以移动到更精确的匹配,您提供的关键字就越多。

这是shuffle.js使用的系统。看看搜索是如何工作的,可能是你想要搜索的内容。

search: function(e) {
       var search = this.$('.search').val();  //pulling in from the search bar
       results = namesCollection.filter(function(item) { return item.get('First_Name').indexOf( search ) !== -1 }); //returns a filtered collection that matches (not exactly) the search results
       filteredCollection.reset(results); //this just resets the current view
}