Найти несколько элементов во вложенном массиве - PullRequest
0 голосов
/ 04 июня 2019

Мне нужно найти несколько элементов во вложенном массиве и вернуть его в виде массива.

Я использую функцию reduce, чтобы найти элементы, но она возвращает только одну запись.

Вложенный массив:

{
    "type": "group",
    "level": 0,
    "expand": "-closed",
    "selected": false,
    "text": "Федулов Владислав Владиславович",
    "phoneNumber": "+7 (927) 999 9999",
    "email": "qweeqwe@mail.ru",
    "id": 24,
    "parent": null,
    "cardType": 0,
    "childrens": [
      {
        "type": "group",
        "level": 1,
        "expand": "-closed",
        "selected": false,
        "text": "Ширяев Феликс Богуславович",
        "phoneNumber": "+7 (123) 456 7810",
        "email": "test@test.ru",
        "id": 47,
        "parent": 24,
        "cardType": 0,
        "childrens": [
          {
            "type": "manager",
            "level": 2,
            "expand": "-empty",
            "selected": false,
            "text": "Колесова Анастасия Олеговна",
            "phoneNumber": "+7 (900) 000 0001",
            "email": "eprosvirina@baccasoft.ru",
            "id": 58,
            "parent": 47,
            "cardType": 0,
            "childrens": null
          }
        ]
      }
    ]
  },
  {
    "type": "group",
    "level": 0,
    "expand": "-closed",
    "selected": false,
    "text": "Игнатьева Женевьева Павловна",
    "phoneNumber": "+7 (777) 777 7777",
    "email": "igp@sks.ru",
    "id": 3,
    "parent": null,
    "cardType": 0,
    "childrens": [
      {
        "type": "group",
        "level": 1,
        "expand": "-closed",
        "selected": false,
        "text": "Меретин Викентий Васильевич",
        "phoneNumber": "+7 (917) 193 5222",
        "email": "keshman@gmail.com",
        "id": 2,
        "parent": 3,
        "cardType": 1,
        "childrens": [
          {
            "type": "manager",
            "level": 2,
            "expand": "-empty",
            "selected": false,
            "text": "Климаков Алексей Александрович",
            "phoneNumber": "+7 (903) 888 8888",
            "email": "krenog@gmail.com",
            "id": 20,
            "parent": 2,
            "cardType": 1,
            "childrens": null
          }
        ]
      }
    ]
  }

и функция reduce:

    var array = store.managersTree.treeNodes;
    var items = [];

    const findItemNested = (arr, searchString, nestingKey) => (
    arr.reduce((a, item) => {
         if (a) return a;
         if (item.text.indexOf(searchString)!==-1 || 
             item.phoneNumber.indexOf(searchString)!==-1 || 
             item.email.indexOf(searchString)!==-1) return item;
         if (item[nestingKey]) return findItemNested(item[nestingKey], 
       searchString, nestingKey)
    }, [])
    );

    const element = findItemNested(array, searchString, "childrens");

Я пытаюсь найти запись, соответствующую хотя бы одному критерию, ожидая, что reduce возвращает несколько записей, но это возвращает только одну запись, несмотря на то, что было найдено несколько записей.

Любая помощь будет оценена.

UPD: searchString может быть строкой типа phoneNumber, text или email

Ответы [ 3 ]

1 голос
/ 04 июня 2019

Вы можете reduce массив рекурсивно.

  • Разрушение объекта в параметре reduce для получения nestingKey и других свойств отдельно
  • Создание массива filterKeys с ключами, которыеВы хотите найти searchString.
  • . Используйте some, чтобы проверить, имеет ли какое-либо из полей объекта значение includes the searchString.
  • Если существует nestingKey, вы можете поместить вложенные элементы в массив аккумуляторов.

const input=[{"type":"group","level":0,"expand":"-closed","selected":false,"text":"Федулов Владислав Владиславович","phoneNumber":"+7 (927) 999 9999","email":"qweeqwe@mail.ru","id":24,"parent":null,"cardType":0,"childrens":[{"type":"group","level":1,"expand":"-closed","selected":false,"text":"Ширяев Феликс Богуславович","phoneNumber":"+7 (123) 456 7810","email":"test@test.ru","id":47,"parent":24,"cardType":0,"childrens":[{"type":"manager","level":2,"expand":"-empty","selected":false,"text":"Колесова Анастасия Олеговна","phoneNumber":"+7 (900) 000 0001","email":"eprosvirina@baccasoft.ru","id":58,"parent":47,"cardType":0,"childrens":null}]}]},{"type":"group","level":0,"expand":"-closed","selected":false,"text":"Игнатьева Женевьева Павловна","phoneNumber":"+7 (777) 777 7777","email":"igp@sks.ru","id":3,"parent":null,"cardType":0,"childrens":[{"type":"group","level":1,"expand":"-closed","selected":false,"text":"Меретин Викентий Васильевич","phoneNumber":"+7 (917) 193 5222","email":"keshman@gmail.com","id":2,"parent":3,"cardType":1,"childrens":[{"type":"manager","level":2,"expand":"-empty","selected":false,"text":"Климаков Алексей Александрович","phoneNumber":"+7 (903) 888 8888","email":"krenog@gmail.com","id":20,"parent":2,"cardType":1,"childrens":null}]}]}],
    filterKeys = ["text", "phoneNumber", "email"];

function findItemNested(array, searchString, nestingKey) {
  return array.reduce((acc, { [nestingKey]: nested, ...o }) => {
    if (filterKeys.some(k => o[k] && o[k].includes(searchString)))
      acc.push(o)
      
    if (nested)
      acc.push(...findItemNested(nested, searchString, nestingKey)) 
      
    return acc;
  }, [])
}

console.log(findItemNested(input, "keshman", "childrens"))
console.log(findItemNested(input, "@gmail.com", "childrens"))
0 голосов
/ 04 июня 2019

Без снижения также возможно,

var s = [{
    "type": "group",
    "level": 0,
    "expand": "-closed",
    "selected": false,
    "text": "Федулов Владислав Владиславович",
    "phoneNumber": "+7 (927) 999 9999",
    "email": "qweeqwe@mail.ru",
    "id": 24,
    "parent": null,
    "cardType": 0,
    "childrens": [
      {
        "type": "group",
        "level": 1,
        "expand": "-closed",
        "selected": false,
        "text": "Ширяев Феликс Богуславович",
        "phoneNumber": "+7 (123) 456 7810",
        "email": "test@test.ru",
        "id": 47,
        "parent": 24,
        "cardType": 0,
        "childrens": [
          {
            "type": "manager",
            "level": 2,
            "expand": "-empty",
            "selected": false,
            "text": "Колесова Анастасия Олеговна",
            "phoneNumber": "+7 (900) 000 0001",
            "email": "eprosvirina@baccasoft.ru",
            "id": 58,
            "parent": 47,
            "cardType": 0,
            "childrens": null
          },
          {
            "type": "group",
            "level": 2,
            "expand": "-empty",
            "selected": false,
            "text": "Колесова Анастасия Олеговна",
            "phoneNumber": "+7 (900) 000 0001",
            "email": "eprosvirina@baccasoft.ru",
            "id": 534,
            "parent": 47,
            "cardType": 0,
            "childrens": null
          },
          {
            "type": "manager",
            "level": 2,
            "expand": "-empty",
            "selected": false,
            "text": "Колесова Анастасия Олеговна",
            "phoneNumber": "+7 (900) 000 0001",
            "email": "eprosvirina@baccasoft.ru",
            "id": 523,
            "parent": 47,
            "cardType": 0,
            "childrens": null
          }
        ]
      }
    ]
  },
  {
    "type": "manager",
    "level": 0,
    "expand": "-closed",
    "selected": false,
    "text": "Игнатьева Женевьева Павловна",
    "phoneNumber": "+7 (777) 777 7777",
    "email": "igp@sks.ru",
    "id": 3,
    "parent": null,
    "cardType": 0,
    "childrens": [
      {
        "type": "group",
        "level": 1,
        "expand": "-closed",
        "selected": false,
        "text": "Меретин Викентий Васильевич",
        "phoneNumber": "+7 (917) 193 5222",
        "email": "keshman@gmail.com",
        "id": 2,
        "parent": 3,
        "cardType": 1,
        "childrens": [
          {
            "type": "manager",
            "level": 2,
            "expand": "-empty",
            "selected": false,
            "text": "Климаков Алексей Александрович",
            "phoneNumber": "+7 (903) 888 8888",
            "email": "krenog@gmail.com",
            "id": 20,
            "parent": 2,
            "cardType": 1,
            "childrens": null
          }
        ]
      }
    ]
  }];

  function filterRequiredElement(arr, searchString, nestingKey) {
      arr.forEach((item, index) => {
          if (item.type !== searchString || item.phoneNumber !== searchString || item.email !== searchString) {
             arr.splice(index, 1);
          }
      });
      for(let item of arr) {
          if (item[nestingKey] !== null) {
              filterRequiredElement(item[nestingKey], searchString, nestingKey);
          }
      }
  }

  filterRequiredElement(s ,'Климаков Алексей Александрович', 'childrens');
  console.log(s);
0 голосов
/ 04 июня 2019

Always Array.reduce возвращает одно значение после обработки каждого элемента в массиве. Если вы хотите вернуть совпадающие записи в массиве, вы можете использовать Array.filter,

[1,2,3,4,5].filter((element) => {
    return (element === 2 || element ===4);
});

Для этого кода выше отфильтрованный массив будет

[2,4]

И перед фильтром вы должны либо выровнять массив, либо пройти через каждый элемент для фильтрации массива вместо использования Array.filter ()

...