javascript - 搜索对象的嵌套数组

标签 javascript arrays reactjs

我正在使用 ReactJs,我需要在对象数组中搜索

这是数组

const menuList = [
  {
    title: "Top 1",
    link: "top1",
  },
  {
    title: "Top 2",
    link: "top2",
    children: [
      {
        title: "Top 2",
        link: "top2",
        parent: true
      },
      {
        title: "Top 2 child 1",
        link: "top2-child-1",
      },
      {
        title: "Top 2 children 2",
        link: "top2-child-2",
        children: [
          {
            title: "deep nested child",
            link: "deep-nested-child"
          }
        ]
      },
      {
        title: "Top 2 child 2",
        link:"top2-child-2"
      },
      {
        title: "Top 2 child 3",
        link: "top2-child-3",
        children: [
          {
            title: "Nested child of Child 3",
            link: "nested-child-of-3"
          }
        ]
      }
    ]
  }
];

我想根据 link 进行搜索,但我想首先在深层子级中搜索,然后在顶部子级中搜索。搜索从最深的子级开始,一直到顶部,直到找到匹配项。如果未找到匹配项,它将返回相同的 menuList。如果找到任何匹配项,那么我想取回该级别的整个数组而不是单个对象。

例如,如果我搜索 top2-child-1 那么它应该返回。

     [
      {
        title: "Top 2",
        link: "top2",
        parent: true
      },
      {
        title: "Top 2 child 1",
        link: "top2-child-1",
      },
      {
        title: "Top 2 children 2",
        link: "top2-child-2",
        children: [
          {
            title: "deep nested child",
            link: "deep-nested-child"
          }
        ]
      },
      {
        title: "Top 2 child 2",
        link:"top2-child-2"
      },
      {
        title: "Top 2 child 3",
        link: "top2-child-3",
        children: [
          {
            title: "Nested child of Child 3",
            link: "nested-child-of-3"
          }
        ]
      }
    ]

我正在尝试的就在这里。

const find_nested_link = (menuList, path) => {
  for (let i = 0; i < menuList.length; i++) {
    if (menuList[i].children) {
      return find_nested_link(menuList[i].children, path);
    } else {
      if (menuList[i].link === path) {
        return menuList;
      }
    }
  }
};

它仅适用于第一个深层嵌套的 child 。如果您搜索nested-child-of-3,它将找不到它。

这是另一个也不是完美的。

const result = menuList.reduce((r, { children }) => {
  let o = children.filter(({ link }) => link === path);
  if (o && o.length) r.push(...children);
  return r;
}, []);

最佳答案

我提供了以下两种方法:

  1. 在树中搜索第一个匹配项,如果找到且包含数组,则返回。
  2. 搜索所有匹配项,返回包含数组、在其中找到它的对象以及在其中找到它的深度

方法一: CodeSandbox

这是一个不使用reduce的递归方法。简单的类型检查来搜索提供的键值,并将搜索任何子数组,其名称不必是“子”。它提供“找到”结果以及找到该结果的数组。您也可以扩展它以返回在其中找到它的对象,非常容易。

const recursivelyFindKeyValue= (key, keyValue, list) => {
  console.log("Searching list: ", list);

  for (let i = 0; i < list.length; i++) {
    const item = list[i];

    for (const key of Object.keys(item)) {
      //check if its array of more options, search it
      if (Array.isArray(item[key])) {
        console.log("child array found, searching", item);
        const res = recursivelyFindKeyValue(key, keyValue, item[key]);
        if (res.found === true) return res;
      }
      //Test the keyValue
      else if (item[key] === keyValue) {
        //found, return the list
        console.log("found ", keyValue);
        return { found: true, containingArray: list };
      }
    }
  }

  return { found: false, containingArray: [] };
};

使用

const res = recursivelyFindKeyValue("link", "top2-child-2", menuList);
const res = recursivelyFindKeyValue("link", "nested-child-of-3", menuList);

方法2: CodeSandbox

此方法将搜索整个树,返回所有结果及其父数组、找到的 key:value 对象以及找到的深度。

const recursivelyFindKeyValue = (key, keyValue, list, depth = 0) => {
  console.log("Searching list: ", list);
  let results = [];

  for (let i = 0; i < list.length; i++) {
    const item = list[i];

    for (const key of Object.keys(item)) {
      //check if its not an array
      if (Array.isArray(item[key])) {
        console.log("child array found, searching", item);
        let res = recursivelyFindKeyValue(key, keyValue, item[key], depth + 1);
        results = results.concat(res);
      }
      //we have found it
      else if (item[key] === keyValue) {
        //found, return the list
        console.log("found ", keyValue);
        results.push({
          found: true,
          containingArray: list,
          depth: depth,
          object: item
        });
      }
    }
  }

  return results;
};

我在codesandbox示例中更深入地创建了另一个链接“top2-child-2”,以便您可以看到多个深度的结果。

关于javascript - 搜索对象的嵌套数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63543618/

相关文章:

javascript - Firebug 不显示我的 javascript?找不到错误

javascript - 带下划线的字符串 Javascript 含义

arrays - 如何在unix中找到数组中的最后一个元素?

javascript - 在javascript中构建层次结构树

javascript - 如何创建 lambda 函数来更新 amplify 上的新记录?

javascript - 如何在服务器上的 recorder.js 中保存音频文件

javascript - 更新状态时,map 不是函数

javascript - 在 reactJS 中,如何将文本复制到剪贴板?

java - 从 RPN 转换为 Infix 时无法检测 2 位数字

javascript - JSON:在文本元素中显示第三级内容(ReactJS/Native)