【问题标题】:Javascript search inside a JSON objectJSON对象内的Javascript搜索
【发布时间】:2012-05-27 14:51:06
【问题描述】:

我的应用程序中有一个 JSON 字符串/对象。

{"list": [
    {"name":"my Name","id":12,"type":"car owner"},
    {"name":"my Name2","id":13,"type":"car owner2"},
    {"name":"my Name4","id":14,"type":"car owner3"},
    {"name":"my Name4","id":15,"type":"car owner5"}
]}

我的应用程序中有一个过滤框,当我在该框中输入名称时,我们必须过滤对象并显示结果。

例如,如果用户输入“姓名”并点击搜索,那么我们必须在 JSON 对象中搜索全名并返回数组,就像 MySQL 搜索一样...

我的问题是用字符串过滤json对象并返回数组......

【问题讨论】:

  • 到目前为止,您尝试过哪些搜索?我们帮助您编写代码,而不是为您提供代码。
  • SO 用于提出问题。你有什么问题?
  • 我使用 jQuery 自动完成功能将我的数据与他们内置的搜索功能联系起来。这可能是您的一个选择,具体取决于您的需要。 jqueryui.com/demos/autocomplete
  • 您是在问如何在 JSON(字符串)或对象(与 JSON 无关)中进行搜索?假设是后者,您是要返回名称匹配的对象数组,还是仅包含名称的数组,还是...?

标签: javascript jquery jsonp json


【解决方案1】:

您可以遍历数组并找到匹配项:

var results = [];
var searchField = "name";
var searchVal = "my Name";
for (var i=0 ; i < obj.list.length ; i++)
{
    if (obj.list[i][searchField] == searchVal) {
        results.push(obj.list[i]);
    }
}

【讨论】:

    【解决方案2】:

    如果您的问题是,是否有一些内置的东西可以为您进行搜索,那么不,没有。您基本上可以使用String#indexOfregular expression 循环遍历数组来测试字符串。

    对于循环,您至少有三个选择:

    1. 一个无聊的老 for 循环。

    2. 在支持 ES5 的环境(或使用 shim)上,Array#filter

    3. 因为您使用的是 jQuery,jQuery.map.

    无聊的老 for 循环示例:

    function search(source, name) {
        var results = [];
        var index;
        var entry;
    
        name = name.toUpperCase();
        for (index = 0; index < source.length; ++index) {
            entry = source[index];
            if (entry && entry.name && entry.name.toUpperCase().indexOf(name) !== -1) {
                results.push(entry);
            }
        }
    
        return results;
    }
    

    您可以将obj.list 称为source 并将所需的名称片段称为name

    或者,如果有任何可能出现空白条目或没有名称的条目,请将if 更改为:

            if (entry && entry.name && entry.name.toUpperCase().indexOf(name) !== -1) {
    

    Array#filter 示例:

    function search(source, name) {
        var results;
    
        name = name.toUpperCase();
        results = source.filter(function(entry) {
            return entry.name.toUpperCase().indexOf(name) !== -1;
        });
        return results;
    }
    

    同样,如果有任何可能存在空白条目(例如,undefined,而不是缺失;filter 将跳过 缺失 条目),将内部返回更改为:

            return entry && entry.name && entry.name.toUpperCase().indexOf(name) !== -1;
    

    jQuery.map 示例(这里我假设jQuery = $ 通常是这种情况;如果您使用的是noConflict,请将$ 更改为jQuery):

    function search(source, name) {
        var results;
    
        name = name.toUpperCase();
        results = $.map(source, function(entry) {
            var match = entry.name.toUpperCase().indexOf(name) !== -1;
            return match ? entry : null;
        });
        return results;
    }
    

    (如果需要,再次添加entry &amp;&amp; entry.name &amp;&amp;。)

    【讨论】:

    • 我觉得这个答案比公认的要详细一点。
    • 对为什么在$.map 被使用的最后一个函数中使用source 感到困惑,因为在那个search 函数中甚至根本没有使用source,这是什么参数点呢?
    • 我想你忘了在这里将source 传递给$.map jQuery 函数。否则,你什么也没有映射。此外,source 需要是要映射的数组,而在这种情况下 sourceobject 不是数组,因此需要先将其传递给 $.makeArray
    • @SolomonClosson:是的,确实重新通过了source,已修复。不过,它是一个数组;问题中的list
    • @Skillzore 据我所知,几乎没有什么重要的事情,尤其是在现代环境中。但即使是旧的也能非常快速处理(比如说)函数调用。
    【解决方案3】:

    您可以简单地将数据保存在变量中,然后使用 JavaScript 的 find(获取单个记录对象)或 filter(获取单个记录数组)方法。

    例如:-

    let data = {
     "list": [
       {"name":"my Name","id":12,"type":"car owner"},
       {"name":"my Name2","id":13,"type":"car owner2"},
       {"name":"my Name4","id":14,"type":"car owner3"},
       {"name":"my Name4","id":15,"type":"car owner5"}
    ]}
    

    现在使用下面的命令 onkeyup 或输入

    获取单个对象

    data.list.find( record => record.name === "my Name")
    

    获取单个数组对象

    data.list.filter( record => record.name === "my Name")
    

    【讨论】:

      【解决方案4】:

      使用PaulGuojSQL,一个使用javascript 的类似SQL 的数据库。例如:

      var db = new jSQL();
      db.create('dbname', testListData).use('dbname');
      var data = db.select('*').where(function(o) {
          return o.name == 'Jacking';
      }).listAll();
      

      【讨论】:

        【解决方案5】:

        我调整了正则表达式来处理 JSON。

        首先,对 JSON 对象进行字符串化。然后,您需要存储匹配子字符串的开头和长度。例如:

        "matched".search("ch") // yields 3
        

        对于 JSON 字符串,它的工作原理完全相同(除非您明确搜索逗号和大括号,在这种情况下,我建议您在执行正则表达式之前先对 JSON 对象进行一些转换(即认为:、{、}) .

        接下来,您需要重构 JSON 对象。我编写的算法通过从匹配索引递归地向后检测 JSON 语法来做到这一点。例如,伪代码可能如下所示:

        find the next key preceding the match index, call this theKey
        then find the number of all occurrences of this key preceding theKey, call this theNumber
        using the number of occurrences of all keys with same name as theKey up to position of theKey, traverse the object until keys named theKey has been discovered theNumber times
        return this object called parentChain
        

        有了这些信息,就可以使用正则表达式过滤一个 JSON 对象以返回键、值和父对象链。

        你可以在http://json.spiritway.co/看到我编写的库和代码

        【讨论】:

        • 嗨,这个答案很旧,但我喜欢它的精神。似乎http链接已过时。我在哪里可以找到你的这个图书馆?
        【解决方案6】:

        如果您在应用程序中的多个位置执行此操作,则使用客户端 JSON 数据库是有意义的,因为创建由 array.filter() 调用的自定义搜索函数比其他方法更麻烦且不易维护.

        查看 ForerunnerDB,它为您提供了一个非常强大的客户端 JSON 数据库系统,并包含一种非常简单的查询语言来帮助您完成您正在寻找的事情:

        // Create a new instance of ForerunnerDB and then ask for a database
        var fdb = new ForerunnerDB(),
            db = fdb.db('myTestDatabase'),
            coll;
        
        // Create our new collection (like a MySQL table) and change the default
        // primary key from "_id" to "id"
        coll = db.collection('myCollection', {primaryKey: 'id'});
        
        // Insert our records into the collection
        coll.insert([
            {"name":"my Name","id":12,"type":"car owner"},
            {"name":"my Name2","id":13,"type":"car owner2"},
            {"name":"my Name4","id":14,"type":"car owner3"},
            {"name":"my Name4","id":15,"type":"car owner5"}
        ]);
        
        // Search the collection for the string "my nam" as a case insensitive
        // regular expression - this search will match all records because every
        // name field has the text "my Nam" in it
        var searchResultArray = coll.find({
            name: /my nam/i
        });
        
        console.log(searchResultArray);
        
        /* Outputs
        [
            {"name":"my Name","id":12,"type":"car owner"},
            {"name":"my Name2","id":13,"type":"car owner2"},
            {"name":"my Name4","id":14,"type":"car owner3"},
            {"name":"my Name4","id":15,"type":"car owner5"}
        ]
        */
        

        免责声明:我是 ForerunnerDB 的开发者。

        【讨论】:

          【解决方案7】:

          这是使用object-scan 的迭代解决方案。好处是你可以很容易地在过滤器函数中做其他处理,并以更易读的格式指定路径。不过,引入依赖项需要权衡取舍,因此这实际上取决于您的用例。

          // const objectScan = require('object-scan');
          
          const search = (haystack, k, v) => objectScan([`list[*].${k}`], {
            rtn: 'parent',
            filterFn: ({ value }) => value === v
          })(haystack);
          
          const obj = { list: [ { name: 'my Name', id: 12, type: 'car owner' }, { name: 'my Name2', id: 13, type: 'car owner2' }, { name: 'my Name4', id: 14, type: 'car owner3' }, { name: 'my Name4', id: 15, type: 'car owner5' } ] };
          
          console.log(search(obj, 'name', 'my Name'));
          // => [ { name: 'my Name', id: 12, type: 'car owner' } ]
          .as-console-wrapper {max-height: 100% !important; top: 0}
          &lt;script src="https://bundle.run/object-scan@13.8.0"&gt;&lt;/script&gt;

          免责声明:我是object-scan的作者

          【讨论】:

            【解决方案8】:

            你可以试试这个:

            function search(data,search) {
                var obj = [], index=0;
                for(var i=0; i<data.length; i++) {
                  for(key in data[i]){
                     if(data[i][key].toString().toLowerCase().indexOf(search.toLowerCase())!=-1) {
                            obj[index] = data[i];
                            index++;
                            break;
                     }
                 }
                 return obj;
            }
            console.log(search(obj.list,'my Name'));
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2014-04-08
              • 2018-05-05
              • 1970-01-01
              • 2011-10-02
              • 2017-07-04
              • 2014-11-28
              • 2018-02-18
              • 2013-04-02
              相关资源
              最近更新 更多