【问题标题】:Javascript Search Nested Object with RegexJavascript 使用正则表达式搜索嵌套对象
【发布时间】:2015-08-31 16:45:09
【问题描述】:

我有这个:

var foo = {
          "Category1": [
            {"Company1": {"URL": ["DomainName1", "DomainName2"]}},
            ...
          ],
          ...
          }

通常,我会像这样访问 DomainName1:

foo["Category1"][0]["Company1"]["URL"][0]

但是,我想在所有foo 中搜索某个域名,但我不知道任何其他信息。我知道我可以使用多个嵌套的 for 循环,但这非常非常很慢。什么是有效的方法来做到这一点?我在想一些类似于'*' 代替["Category1"][0] 等的东西,但我不知道该怎么做。

任何帮助将不胜感激。

【问题讨论】:

  • 您的foo 对象有多大?树是固定结构还是嵌套层数可以非常多?您究竟在搜索什么:URL 值或foo 中的“地址”? 非常非常慢是什么意思?希望它有多快?从你的话我想你还没有尝试过递归解决方案......
  • 那么你想要什么,对类别、公司或网址的引用?
  • 您可能想要重组数据,以便搜索变得更加高效。例如。 [[url, [company, ...], ...](已排序)并执行二分查找。
  • 我认为编写正则表达式将是一项艰巨的任务,并且可能不会比循环表现更好
  • 正如 Felix 所说,如果数据变化不大,最好建立一个索引并使用它。我会使用如下对象:{url1: [company1, company2], url2: [comany3, company4],...} 其中 company 是对相关公司对象的引用或作为字符串的名称,无论适合什么。

标签: javascript regex json object nested


【解决方案1】:

我的回答可能是固执己见,但仍然...使用 数万 个对象,您正试图重新发明轮子。这是数据库存储的确切候选者。 SQL 或非 SQL,如 MongoDB。

【讨论】:

    【解决方案2】:

    Jsonpath解决这个问题很好。

    例如,您可以使用此表达式来查找所有 URL:

    var out = jsonPath(json, "$..URL[*]").toJSONString() + "\n";
    document.write(out);
    

    您可以使用表达式来匹配您想要的域。

    对于您的情况,您可以使用以下表达式:

    $..URL[?(@.indexOf('DomainName1') != -1)]
    

    Jsonpath online tool

    这是一个来自 documentation 的有用 Jsonpath 示例:

    <html>
    <head>
    <title> JSONPath - Example (js)</title>
    <script type="text/javascript" src="json.js"></script>
    <script type="text/javascript" src="jsonpath.js"></script>
    </head>
    <body>
    <pre>
    <script type="text/javascript">
       var json = 
                      { "store": {
                            "book": [ 
                              { "category": "reference",
                                    "author": "Nigel Rees",
                                    "title": "Sayings of the Century",
                                    "price": 8.95
                              },
                              { "category": "fiction",
                                    "author": "Evelyn Waugh",
                                    "title": "Sword of Honour",
                                    "price": 12.99
                              },
                              { "category": "fiction",
                                    "author": "Herman Melville",
                                    "title": "Moby Dick",
                                    "isbn": "0-553-21311-3",
                                    "price": 8.99
                              },
                              { "category": "fiction",
                                    "author": "J. R. R. Tolkien",
                                    "title": "The Lord of the Rings",
                                    "isbn": "0-395-19395-8",
                                    "price": 22.99
                              }
                            ],
                            "bicycle": {
                              "color": "red",
                              "price": 19.95
                            }
                      }
                    },
               out = "";
           out += jsonPath(json, "$.store.book[*].author").toJSONString() + "\n>";
           out += jsonPath(json, "$..author").toJSONString() + "\n";
           out += jsonPath(json, "$.store.*").toJSONString() + "\n";
           out += jsonPath(json, "$.store..price").toJSONString() + "\n";
           out += jsonPath(json, "$..book[(@.length-1)]").toJSONString() + "\n";
           out += jsonPath(json, "$..book[-1:]").toJSONString() + "\n";
           out += jsonPath(json, "$..book[0,1]").toJSONString() + "\n";
           out += jsonPath(json, "$..book[:2]").toJSONString() + "\n";
           out += jsonPath(json, "$..book[?(@.isbn)]").toJSONString() + "\n";
           out += jsonPath(json, "$..book[?(@.price<10)]").toJSONString() + "\n";
           out += jsonPath(json, "$..*").toJSONString() + "\n";
           document.write(out);
      </script>
    </pre>
    </body>
    </html>
    

    示例输出:

    ["Nigel Rees","Evelyn Waugh","Herman Melville","J. R. R. Tolkien"]
    ["Nigel Rees","Evelyn Waugh","Herman Melville","J. R. R. Tolkien"]
    [[{"category":"reference","author":"Nigel Rees","title":"Sayings of the Century","price":8.95},{"category":"fiction","author":"Evelyn Waugh","title":"Sword of Honour","price":12.99},{"category":"fiction","author":"Herman Melville","title":"Moby Dick","isbn":"0-553-21311-3","price":8.99},{"category":"fiction","author":"J. R. R. Tolkien","title":"The Lord of the Rings","isbn":"0-395-19395-8","price":22.99}],{"color":"red","price":19.95}]
    [8.95,12.99,8.99,22.99,19.95]
    [{"category":"fiction","author":"J. R. R. Tolkien","title":"The Lord of the Rings","isbn":"0-395-19395-8","price":22.99}]
    [{"category":"fiction","author":"J. R. R. Tolkien","title":"The Lord of the Rings","isbn":"0-395-19395-8","price":22.99}]
    [{"category":"reference","author":"Nigel Rees","title":"Sayings of the Century","price":8.95},{"category":"fiction","author":"Evelyn Waugh","title":"Sword of Honour","price":12.99}]
    [{"category":"reference","author":"Nigel Rees","title":"Sayings of the Century","price":8.95},{"category":"fiction","author":"Evelyn Waugh","title":"Sword of Honour","price":12.99}]
    [{"category":"fiction","author":"Herman Melville","title":"Moby Dick","isbn":"0-553-21311-3","price":8.99},{"category":"fiction","author":"J. R. R. Tolkien","title":"The Lord of the Rings","isbn":"0-395-19395-8","price":22.99}]
    [{"category":"reference","author":"Nigel Rees","title":"Sayings of the Century","price":8.95},{"category":"fiction","author":"Herman Melville","title":"Moby Dick","isbn":"0-553-21311-3","price":8.99}]
    [{"book":[{"category":"reference","author":"Nigel Rees","title":"Sayings of the Century","price":8.95},{"category":"fiction","author":"Evelyn Waugh","title":"Sword of Honour","price":12.99},{"category":"fiction","author":"Herman Melville","title":"Moby Dick","isbn":"0-553-21311-3","price":8.99},{"category":"fiction","author":"J. R. R. Tolkien","title":"The Lord of the Rings","isbn":"0-395-19395-8","price":22.99}],"bicycle":{"color":"red","price":19.95}},[{"category":"reference","author":"Nigel Rees","title":"Sayings of the Century","price":8.95},{"category":"fiction","author":"Evelyn Waugh","title":"Sword of Honour","price":12.99},{"category":"fiction","author":"Herman Melville","title":"Moby Dick","isbn":"0-553-21311-3","price":8.99},{"category":"fiction","author":"J. R. R. Tolkien","title":"The Lord of the Rings","isbn":"0-395-19395-8","price":22.99}],{"color":"red","price":19.95},{"category":"reference","author":"Nigel Rees","title":"Sayings of the Century","price":8.95},{"category":"fiction","author":"Evelyn Waugh","title":"Sword of Honour","price":12.99},{"category":"fiction","author":"Herman Melville","title":"Moby Dick","isbn":"0-553-21311-3","price":8.99},{"category":"fiction","author":"J. R. R. Tolkien","title":"The Lord of the Rings","isbn":"0-395-19395-8","price":22.99},"reference","Nigel Rees","Sayings of the Century",8.95,"fiction","Evelyn Waugh","Sword of Honour",12.99,"fiction","Herman Melville","Moby Dick","0-553-21311-3",8.99,"fiction","J. R. R. Tolkien","The Lord of the Rings","0-395-19395-8",22.99,"red",19.95]
    

    只需使用您想要的表达式即可轻松查询您的 json 结构。

    【讨论】:

    • 我想知道这会比直接使用纯 javascript 迭代属性更快...
    • @KirillSlatin jsonpath 是过滤大型 json 的工具,既然已经有工具可以帮助处理 json 查询,为什么还要重新发明轮子……
    • 所有+= 都会非常慢。
    • 问题不在于+=... 正则表达式解析会产生开销,这是肯定的。而且没有算法改进,只是语法糖。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多