编写递归搜索函数以返回对象;

时间:2019-06-22 04:26:51

标签: javascript arrays angular google-cloud-firestore

我正在尝试编写一个搜索功能,该功能可以搜索对象数组的数组并返回名称中包含搜索字符串的所有对象。

我遇到的问题是对象数组可以包含一个孩子数组,而这些孩子也可以有一个孩子数组。我需要动态搜索所有可能的子代并返回结果

我尝试使用Algolia进行此操作,但是由于文件结构不会不断更新,因此我觉得使用Array.includes或类似的东西会更好

我尝试了以下功能,但似乎无法正常工作

  searchArray(subMenuItems, name) {
    if (subMenuItems) {
      for (let i = 0; i < subMenuItems.length; i++) {
        if (subMenuItems.includes(name)) {
          return subMenuItems[i];
        }
        const found = this.getSubItem(subMenuItems[i].children, name);
        if (found) {
          return found;
        }
      }
    }
  }

这是对象数组的一个例子

[
   [
      {
         "children":[
            {
               "children":[
                  {
                     "fileSize":"1.2MB",
                     "fileUrl":"https://linktoPDF.com",
                     "name":"GF Kitchen ",
                     "type":"file"
                  }
               ],
               "name":"Ground Floor Kitchen",
               "type":"folder"
            }
         ],
         "name":"House",
         "type":"folder"
      }
   ],
   [
      {
         "fileSize":"1.3MB",
         "fileUrl":"https://linktoPDF.com",
         "name":"Introduction and Overview",
         "type":"file"
      },
      {
         "fileSize":"20MB",
         "fileUrl":"https://linktoPDF.com",
         "name":"VISUAL iPad Location Drawing",
         "type":"file"
      },
      {
         "fileSize":"1MB",
         "fileUrl":"https://linktoPDF.com",
         "name":"Control Surface",
         "type":"file"
      },
      {
         "fileSize":"1.3MB",
         "fileUrl":"https://linktoPDF.com",
         "name":"Scene",
         "type":"file"
      }
   ]
]

2 个答案:

答案 0 :(得分:0)

一个简单的递归函数将允许您从每个嵌套的对象(无论深度如何)中收集对象(或对象的任何属性)。

您应该考虑是否区分大小写也很重要。

否则,这将起作用:

  • 在数据中搜索带有“ ce”的任何名称
  • 然后搜索带有“ tion”的任何名称
  • 然后搜索带有“ Floor”的任何名称

const data = [[{"children":[{"children":[{"fileSize":"1.2MB","fileUrl":"https://linktoPDF.com","name":"GF Kitchen","type":"file"}],"name":"Ground Floor Kitchen","type":"folder"}],"name":"House","type":"folder"}],[{"fileSize":"1.3MB","fileUrl":"https://linktoPDF.com","name":"Introduction and Overview","type":"file"},{"fileSize":"20MB","fileUrl":"https://linktoPDF.com","name":"VISUAL iPad Location Drawing","type":"file"},{"fileSize":"1MB","fileUrl":"https://linktoPDF.com","name":"Control Surface","type":"file"},{"fileSize":"1.3MB","fileUrl":"https://linktoPDF.com","name":"Scene","type":"file"}]];
let output = [];

function search(arr, str) {
  arr.forEach(a => {
    if (a.constructor == Array) {
      search(a, str);
    } else if (a.children) {
      if (a.name.includes(str)) output.push(a);
      search(a.children, str);
    } else {
      if (a.name.includes(str)) output.push(a);
    }

  });
}
search(data, 'ce');
console.log(output);
output = [];
search(data, 'tion');
console.log(output);
output = [];
search(data, 'Floor');
console.log(output);

答案 1 :(得分:0)

您可以尝试如下所示的递归函数来检查数组和子数组以获取结果。

function searchByName(obj, name) {
  if (Array.isArray(obj)) {
    return obj.reduce((acc, item) => acc.concat(searchByName(item, name)), []);
  }
  if (typeof obj === 'object') {
    const matched = [];
    const { children, ...rest } = obj;
    if (obj.name && obj.name.includes(name)) {
      matched.push(rest);
    }
    return Array.isArray(children) ?
      matched.concat(searchByName(children, name)) : matched;
  }
  return;
}

const arr = [[{"children":[{"children":[{"fileSize":"1.2MB","fileUrl":"https://linktoPDF.com","name":"GF Kitchen","type":"file"}],"name":"Ground Floor Kitchen","type":"folder"}],"name":"House","type":"folder"}],[{"fileSize":"1.3MB","fileUrl":"https://linktoPDF.com","name":"Introduction and Overview","type":"file"},{"fileSize":"20MB","fileUrl":"https://linktoPDF.com","name":"VISUAL iPad Location Drawing","type":"file"},{"fileSize":"1MB","fileUrl":"https://linktoPDF.com","name":"Control Surface","type":"file"},{"fileSize":"1.3MB","fileUrl":"https://linktoPDF.com","name":"Scene","type":"file"}]];

console.log(searchByName(arr, 'not found'));
console.log(searchByName(arr, 'Drawing'));
console.log(searchByName(arr, 'S'));