Как обойти вложенный массив и получить из него все объекты с совпадениями по value?

Я написал функцию фильтрации по массиву, но функция не попадает во вложенные элементы массива, как мне реализовать поиск по всему массиву и возврат отфильтрованного массива по значению value в таких ключах как code | name | searchWords?

Пример данных для поиска совпадения по вложенному массиву по таким полям/ключам как code | name | searchWords

Ниже приведен пример функции которая фильтрует массив исходя из введённых значений value.

const dataSourse = [{
  "id": "18c12ce6-5b79-4d44-939c-4b7e864883d1",
  "code": "Пожарная охрана",
  "name": "Пожарная охрана",
  "searchWords": null,
  "caseTypeId": "6d884bfa-4283-4393-9cf9-c44280af4752",
  "priority": 0,
  "childIndexes": [{
    "id": "3ea51dbe-dd0b-49c4-a274-e8b361e765dc",
    "code": "301",
    "name": "Пожар",
    "searchWords": null,
    "caseTypeId": null,
    "priority": 2,
    "childIndexes": [{
      "id": "b20b4749-bd2f-408c-a593-454f0df094a0",
      "code": "30026",
      "name": "Автобус",
      "searchWords": null,
      "caseTypeId": null,
      "priority": 3,
      "childIndexes": [],
      "isVisible": true,
      "orderNumber": 2
    }, {
      "id": "57a08dc4-5d06-4561-884a-dc4c992fbaaf",
      "code": "30032",
      "name": "АЗС",
      "searchWords": null,
      "caseTypeId": null,
      "priority": 3,
      "childIndexes": [],
      "isVisible": true,
      "orderNumber": 8
    }, {
      "id": "cdd9e3bc-dabb-4d9a-a3af-47cbfeabc776",
      "code": "30047",
      "name": "Ж/Д вокзал",
      "searchWords": null,
      "caseTypeId": null,
      "priority": 3,
      "childIndexes": [],
      "isVisible": true,
      "orderNumber": 9
    }],
    "isVisible": true,
    "orderNumber": 1
  }, {
    "id": "c1195457-8225-4576-a33e-5bae71b0a365",
    "code": "303",
    "name": "Разлив топлива",
    "searchWords": "бензин, дизель",
    "caseTypeId": null,
    "priority": 2,
    "childIndexes": [],
    "isVisible": true,
    "orderNumber": 6
  }, {
    "id": "b93b2802-fb29-4232-baa9-72e8f5d12ce3",
    "code": "302",
    "name": "Задымление",
    "searchWords": null,
    "caseTypeId": null,
    "priority": 2,
    "childIndexes": [],
    "isVisible": true,
    "orderNumber": 7
  }, {
    "id": "fd9f4fb9-b7ae-46f1-ae89-784d66b5f182",
    "code": "001",
    "name": "Возгорание машины",
    "searchWords": "машина пожар",
    "caseTypeId": null,
    "priority": 1,
    "childIndexes": [],
    "isVisible": false,
    "orderNumber": 32
  }],
  "isVisible": true,
  "orderNumber": 1
}]

function onSearch(tree, value) {
  const keys = ['code', 'name', 'searchWords']
  const items = [];
  for (item of tree) {
    if (!item.childIndexes) return;
    if (item.childIndexes) {
      const currentTree = item.childIndexes.filter((child) => {
        return (Object.keys(child).some((k) => {
          return (String(child[k]).toLowerCase().includes(value.toLowerCase()))
        }))
      })
      items.push(currentTree)
    }
  }
  console.log(items)
  return items
}
const values = 'в'

console.log(onSearch(dataSourse, values));


Ответы (1 шт):

Автор решения: Dmitry Kozlov

Надо добавить рекурсивный вызов самой себя в функции. Также убрал возврат текущего массива. Переменную аккумулятор вынес за пределы функции.

const dataSourse = [{
  "id": "18c12ce6-5b79-4d44-939c-4b7e864883d1",
  "code": "Пожарная охрана",
  "name": "Пожарная охрана",
  "searchWords": null,
  "caseTypeId": "6d884bfa-4283-4393-9cf9-c44280af4752",
  "priority": 0,
  "childIndexes": [{
    "id": "3ea51dbe-dd0b-49c4-a274-e8b361e765dc",
    "code": "301",
    "name": "Пожар",
    "searchWords": null,
    "caseTypeId": null,
    "priority": 2,
    "childIndexes": [{
      "id": "b20b4749-bd2f-408c-a593-454f0df094a0",
      "code": "30026",
      "name": "Автобус",
      "searchWords": null,
      "caseTypeId": null,
      "priority": 3,
      "childIndexes": [],
      "isVisible": true,
      "orderNumber": 2
    }, {
      "id": "57a08dc4-5d06-4561-884a-dc4c992fbaaf",
      "code": "30032",
      "name": "АЗС",
      "searchWords": null,
      "caseTypeId": null,
      "priority": 3,
      "childIndexes": [],
      "isVisible": true,
      "orderNumber": 8
    }, {
      "id": "cdd9e3bc-dabb-4d9a-a3af-47cbfeabc776",
      "code": "30047",
      "name": "Ж/Д вокзал",
      "searchWords": null,
      "caseTypeId": null,
      "priority": 3,
      "childIndexes": [],
      "isVisible": true,
      "orderNumber": 9
    }],
    "isVisible": true,
    "orderNumber": 1
  }, {
    "id": "c1195457-8225-4576-a33e-5bae71b0a365",
    "code": "303",
    "name": "Разлив топлива",
    "searchWords": "бензин, дизель",
    "caseTypeId": null,
    "priority": 2,
    "childIndexes": [],
    "isVisible": true,
    "orderNumber": 6
  }, {
    "id": "b93b2802-fb29-4232-baa9-72e8f5d12ce3",
    "code": "302",
    "name": "Задымление",
    "searchWords": null,
    "caseTypeId": null,
    "priority": 2,
    "childIndexes": [],
    "isVisible": true,
    "orderNumber": 7
  }, {
    "id": "fd9f4fb9-b7ae-46f1-ae89-784d66b5f182",
    "code": "001",
    "name": "Возгорание машины",
    "searchWords": "машина пожар",
    "caseTypeId": null,
    "priority": 1,
    "childIndexes": [],
    "isVisible": false,
    "orderNumber": 32
  }],
  "isVisible": true,
  "orderNumber": 1
}]

const items = [];

function onSearch(tree, value) {
  const keys = ['code', 'name', 'searchWords']
  for (item of tree) {
    if (!item.childIndexes) return;
    if (item.childIndexes) {
      const currentTree = item.childIndexes.filter((child) => {
        return (Object.keys(child).some((k) => {
          return (String(child[k]).toLowerCase().includes(value.toLowerCase()))
        }))
      })
      items.push(currentTree)
      if (currentTree.childIndexes) {
        onSearch(currentTree, value);
      }
    }
  }
}
const values = 'з'
onSearch(dataSourse, values);

console.log(items);

→ Ссылка