代码之家  ›  专栏  ›  技术社区  ›  SamCharles

在JavaScript的对象数组中查找对象数组中不区分大小写的子字符串

  •  1
  • SamCharles  · 技术社区  · 1 年前

    我不知道如何在JavaScript中处理嵌套数组和对象。我需要检查是否有任何标题(无论是主文件夹标题还是目录中的标题)包含某种不区分大小写的单词(示例代码中的信息)。一旦在任何标题中找到单词,它就可以停止检查。我需要跳过/忽略描述。

    const data = [{
        "Title": "folder title 1",
        "Id": 857412,
        "Description": { "Text": "description 1" },
        "Contents": [
            { "Title": "contents 1 title 1", "Id": 123456 },
            { "Title": "contents 1 title 2 - Information", "Id": 987654 }
        ]
    },{
        "Title": "folder title 2",
        "Id": 895623,
        "Description": { "Text": "description 2" },
        "Contents": [
            { "Title": "contents 2 title 3", "Id": 784512 }
        ]
    }];
    
    const contents = data.map(item => ({Contents:item.Contents}));
    const folders = data.map(item => ({Title:item.Title}));
    const combinedData = contents.concat(folders);
    const stringData = JSON.stringify(combinedData);
    console.log(stringData.toLowerCase().includes("information"));

    我的代码可以工作,但我100%确定有更好的方法来做到这一点,我不确定每次要处理多少数据。我只是无法理解对象数组中的对象数组,而且我对JavaScript还太陌生,无法理解许多方法。网站上的例子过于简单,数组中只有几个数字,这对这些数据没有帮助。

    有什么更好的方法可以使用?我如何同时检查文件夹和内容的标题,同时忽略描述,而不需要连接和字符串化来查找单词?谢谢你的建议!

    1 回复  |  直到 1 年前
        1
  •  3
  •   Barmar    1 年前

    不要将所有内容连接起来,只需使用 Array.some() 在顶级数组或嵌套数组中搜索匹配的标题 Contents 阵列。一旦找到匹配项,它就会停止。

    function titlesIncludes(data, search) {
      search = search.toLowerCase();
      return data.some(item =>
        item.Title.toLowerCase().includes(search) ||
        item.Contents.some(content => content.Title.toLowerCase().includes(search)));
    }
    
    console.log(titlesIncludes(data, "information"));
    console.log(titlesIncludes(data, "nothing"));
    <script>
      const data = [{
        "Title": "folder title 1",
        "Id": 857412,
        "Description": {
          "Text": "description 1"
        },
        "Contents": [{
            "Title": "contents 1 title 1",
            "Id": 123456
          },
          {
            "Title": "contents 1 title 2 - Information",
            "Id": 987654
          }
        ]
      }, {
        "Title": "folder title 2",
        "Id": 895623,
        "Description": {
          "Text": "description 2"
        },
        "Contents": [{
          "Title": "contents 2 title 3",
          "Id": 784512
        }]
      }];
    </script>
        2
  •  0
  •   Roko C. Buljan    1 年前

    Barmar的回答很好 明确地 解决您的问题
    说起 文件夹 内容 我们可以很容易地谈论 Tree Nodes .
    此外 文件夹 ,文件夹的 目录 也可以很容易地拥有 子文件夹 以此类推,所以这是我的两分:

    创建一个递归函数,用于检查 深嵌套 节点

    /** Get Contents' node by key value; case-insensitive */
    const getNode = (arr = [], prop = "", val = "") => {
      for (const node of arr) {
        if (node[prop].toLowerCase().includes(val.toLowerCase())) return node;
        const res = getNode(node.Contents, prop, val);
        if (res) return res;
      }
    };
    
    // Use like:
    console.log(getNode(data, "Title", "information"));
    // Or like:
    if (getNode(data, "Title", "information")) { console.log("found"); };
    

    这样你就可以有尽可能多的嵌套 Contents 节点,如您所愿。
    如本例所示:

    const data = [{
        "Title": "folder title 1",
        "Id": 857412,
        "Description": {
          "Text": "description 1"
        },
        "Contents": [{
            "Title": "contents 1 title 1",
            "Id": 123456
          },
          {
            "Title": "contents 1 title 2",
            "Id": 987654
          }
        ]
      },
      {
        "Title": "folder title 2",
        "Id": 895623,
        "Description": {
          "Text": "description 2"
        },
        "Contents": [{
          "Title": "contents 2 title 3",
          "Id": 784512
        }, {
          "Title": "SUBFOLDER",
          "Id": 999999,
          "Contents": [{
            "Title": "contents 3 title 3 - Information",
            "Id": 987654
          }]
        }]
      }
    ];
    
    /** Get Contents' node by key value; case-insensitive */
    const getNode = (arr = [], prop = "", val = "") => {
      for (const node of arr) {
        if (node[prop].toLowerCase().includes(val.toLowerCase())) return node;
        const res = getNode(node.Contents, prop, val);
        if (res) return res;
      }
    };
    
    console.log(getNode(data, "Title", "information"));
    if (getNode(data, "Title", "information")) {
      console.log("found");
    };