【问题标题】:Javascript Search in Object Array Like SQL By Object KeyJavascript 在对象数组中像 SQL 一样按对象键搜索
【发布时间】:2014-02-18 11:16:10
【问题描述】:

例如,我有一个这样的数组:

var arr = [
    {"keyword": "Sample 1", "item": {"title":"Sample Title", "url": "/sample"}},
    {"keyword": "Foo 1", "item": {"title":"Foo Title", "url": "/sample"}}
];

我想在“关键字”键中进行搜索,例如当用户从他们的输入中按下一个键并返回匹配的对象时。

如果用户按下“s”键,则首先是 [0],元素必须返回。就像使用 SQL LIKE 语句一样。

$("#query").on('keypress', function () {
    var result = $.grep(keywords, function(e){
    //I do not know what should i do here.    
    });
});

【问题讨论】:

    标签: javascript jquery arrays object grep


    【解决方案1】:

    如果你想使用$.grep,你可以这样做:

    $("#query").on('keyup', function() {
        var search = this.value.toLowerCase();
        var result = $.grep(keywords, function(el) {
            return el.keyword.toLowerCase().indexOf(search) > -1;
        });
    });
    

    演示:http://jsfiddle.net/9TPSa/

    另外请注意,我切换到keyup 事件以便能够读取更新的this.value

    【讨论】:

    • 谢谢。这正是我想要的!
    • 它确实会循环,@R.CanserYanbakan,所以如果你想避免这种情况:使用 $.grep() 时不要这样做。
    • 它应该遍历所有元素以找到所有匹配的行。但是为了提高性能我也建议使用原生的for-loop 更好。
    • 这使得它与手动循环一样高效,只是更方便(但是,是的,它确实做到了后者)。因此,如果该数组中确实有约 1000 个对象(如对我的回答的评论中所述),这确实不是一件好事,尤其不是每次都这样做。由于 jQuery 本身是用 Javascript 编写的,因此您甚至不具备本机代码的速度优势(@tewathia 建议的Array.prototype.filter 有这个)。
    • @R.CanserYanbakan 然后改成return el.keyword.toLowerCase().indexOf(search) == 0;0 表示出现位置,第一个字母。
    【解决方案2】:

    使用Array.prototype.filter 方法:

    Array.prototype.filterBy = function(attr, value) {
        return this.filter(function(elem){
            return elem[attr].indexOf(value) !== -1;
        });
    }
    

    然后arr.filterBy('keyword', '1') 将返回两个对象(在您的arr 数组中),而arr.filterBy('keyword', 'oo') 将只返回第二个。

    DEMO

    【讨论】:

    • 我试过这个但没有奏效。我错过了什么吗?您能否为我和像我一样搜索答案的人提供一个可行的示例?如果我们看上面的例子,可能会导致性能问题。
    【解决方案3】:

    答案很简单:您必须遍历所有对象,查看每个 keyword 条目并确定它是否与您的搜索匹配。像这样的东西:

    var results = [];
    for (var i = 0 ; i < arr.length ; i++) {
        if (arr[i].keyword == "what ever you are looking for") {
            results.push(arr[i]);
        }
    }
    

    如果您只需要第一个匹配项(而不是全部),您可以简化它:

    var result;
    for (var i = 0 ; i < arr.length ; i++) {
        if (arr[i].keyword == "what ever you are looking for") {
            result = arr[i];
            break;
        }
    }
    

    如果您不是在寻找平等,但需要使用占位符,请查看String.prototype.indexOf()regular expressions

    如果你想不惜一切代价使用$.grep()(虽然手动循环并没有太大区别,它也会循环,只是在内部循环),你可以 - 它看起来像这样:

    $("#query").on('keypress', function () {
        var result = $.grep(keywords, function(e){
            return (e.keyword == "whatever you are looking for again");
            // use regular expressions or .indexOf again if you don't want to test equallity
        });
    });
    

    但是,循环遍历大型结构(当您与数据库进行比较时,我怀疑您在 arr 中有很多这些对象?)但是效率非常低。您必须循环的事实表明设计不佳。如果你真的有很多,你可以考虑使用支持索引的数据结构,比如Hash Table/Map(这些没有在核心 Java API 中实现;但很容易在 yoru 上实现)。但是,如果您需要占位符,它们将不起作用,它们仅在使用相等来匹配结果时才有优势。

    【讨论】:

    • 在这种情况下循环是一个坏主意。该数组有 1000~ 个对象。我会检查哈希表谢谢你的信息。
    • 参见 eidt:$.grep 也会循环,Array.prototype.filter 和任何其他过滤数组/集合/任何内容的方法也是如此。
    • 你是对的,但我不想自己这样做 :) 对不起。
    • “那”是“实现一个 HashTable(或任何其他搜索优化的数据结构 - 还有更多)?如果是这样,我敢打赌有支持这些的库,我只是不知道. 谷歌可能 ;) 唯一的替代方法是循环(一种或另一种方式)。
    【解决方案4】:

    您可以尝试使用 jQuery UI 的 AutoComplete...http://jqueryui.com/autocomplete/

    您必须将数组缩减为您希望可搜索的字段(即关键字属性的字符串文字,如@9​​87654324@)并将其作为sourceautocomplete 中传递选项。

    然后挂钩到change 事件http://api.jqueryui.com/autocomplete/#event-change 并从原始数组中提取对象的其余部分。

    编辑:如果您想使用 grep,这里有一个使用该方法获取结果的示例,但是下一步是如何将它们显示为自动选项!

    http://jsfiddle.net/eQp3h/

    var arr = [
        {"keyword": "Sample 1", "item": {"title":"Sample Title", "url": "/sample"}},
        {"keyword": "Foo 1", "item": {"title":"Foo Title", "url": "/sample"}}
    ];
    
    
    $("#query").on('keyup', function () {
        var regExp = new RegExp("^" + $(this).val(), "i");
    
        var result = $.grep(arr, function(e, i){
            var match = regExp.test(e.keyword);
            return match;
        });
    
        $("#results").text(JSON.stringify(result));
    });
    

    【讨论】:

    • 是的。我认为这是但我不想首先减少我的数组。我想用 grep 之类的函数来做到这一点。
    • 很公平,尽管首先执行某种减少可能更有效,否则您将处理每个可能需要考虑的按键:)
    • 是的。我明白。也许我稍后会减少我的数组,但首先我需要学习如何做到这一点:) 谢谢!
    • 刚刚编辑了一个使用 grep 的示例,您必须从回调函数返回 true 或 false,该回调函数将在数组的每个元素上调用。所以在这里我只是检查元素以查看字符串的开头是否与输入的内容匹配。祝你好运!
    【解决方案5】:

    试试这个

        $("body").on("keyup","#query",function(e){
            var str = $("#query").val().toLowerCase();
            var newarr = $.grep(arr,function(n,i){
                return n.keyword.toLowerCase().search(str)!=-1;
            });
        });
    

    【讨论】:

      猜你喜欢
      • 2013-04-02
      • 1970-01-01
      • 2011-04-07
      • 2017-05-14
      • 2018-03-25
      • 2019-02-12
      • 1970-01-01
      • 2018-01-05
      • 1970-01-01
      相关资源
      最近更新 更多