Вложенный массив поискового фильтра, получающий модифицированный исходный массив после Object.Assign - PullRequest
0 голосов
/ 14 мая 2019

Попытка реализовать фильтр поиска для вложенного массива на двух уровнях на основе цифр: если цифры / числа соответствуют какой-либо последовательности в моей структуре данных, результаты должны точно совпадать с критериями поиска:

Моя структура данных: исходный массив

TreeRange:
    {
        tree: '17200',
        treeRanges: [
          {
            id: 134055,
            strttreeNum: '5308550000000000000',
            endngtreeNum: '5308559999999999999',
            treeregistered [
              {
                id: 9,
                branch: '12345678989895559'
              },
              {
                id: 10,
                branch: '78912349494945449'
              }
            ]
          },
          {
               id: '23175',
               strttreeNum: '1234309999999999999',
               endngtreeNum: '3466309999999999999',
               treeregistered: [
                 {
                   id: 14,
                   branch: '5500001231234234'
                 },
                 {
                   id: 15,
                   branch: '5598761234444234' 
                 }
               ]
           }
        ]
    }

Текущий вывод: SearchFilterArray:

           {
               id: '23175',
               strttreeNum: '1234309999999999999',
               endngtreeNum: '3466309999999999999',
               treeregistered: [
                 {
                   id: 14,
                   branch: '5500001234444234'//only show this in search result
                 },
                 {
                   id: 15,
                   branch: '5598761230000234' //**Not suppose show this record**
                 }
               ]
           }

ожидаемый результат: SearchFilterArray:

Поиск по SearchTerm: 4444

TreeRange: 
   {
        tree: '17200',
        treeRanges: [
          {
               id: '23175',
               strttreeNum: '1234309999999999999',
               endngtreeNum: '3466309999999999999',
               treeregistered: [
                 {
                   id: 15,
                   branch: '5598761234444234'
                 }
               ]
           }
        ]
    }

когда я очищаю поиск, исходный вложенный древовидный зарегистрированный массив должен быть сброшен в Original Array, показанный выше. код:

{
if (!searchTerm || searchTerm === '') {
  return treeRange;
}
let filterArray = treeRange.map(aRanges => Object.assign({}, aRanges));
filterArray = filterArray.filter(
  treeRange1 =>
    treeRange1.tree.includes(searchTerm) ||
    treeRange1.treeRanges.some(
      treeinRange =>
        treeinRange.strttreeNum.includes(searchTerm) ||
        treeinRange.endngtreeNum.includes(searchTerm) ||
        treeinRange.treeregistered.some(
          treereg =>
            treereg.branch.includes(searchTerm)
        )
    ));

filterArray =  filterArray.map(filterTreeRange => {
  filterTreeRange.treeRanges = filterTreeRange.treeRanges.filter(filTreeRange =>
    filTreeRange.strttreeNum.includes(searchTerm) ||
    filTreeRange.endngtreeNum.includes(searchTerm) ||
    filterTreeRange.tree.includes(searchTerm) ||
    filTreeRange.treeregistered.some(
    treReg =>
      treReg.branch.includes(searchTerm)
    )
  );
  return filterTreeRange;
});
return filterArray;

}

работает, когда я ищу treeRanges и возвращает отфильтрованные результаты, но зарегистрированный в дереве массив не фильтруется в соответствии с searchTerm, я добавил еще один фильтр ниже: проблема в том, что мой оригинальный зарегистрированный в виде дерева вложенный массив модифицируется, когда я выполняю поиск и когда я очищаю поиск у меня нет оригинального массива. object.assign работает для вложенного массива treeRanges, но не для зарегистрированного вложенного массива

filterArray =  filterArray.map(filterTreeRange => {
      filterTreeRange.treeRanges = filterTreeRange.treeRanges.filter(filTreeRange => {
          filTreeRange.treeregistered = filTreeRange.treeregistered.filter(
            treReg =>
              treReg.branch.includes(searchTerm) ||
              filTreeRange.strttreeNum.includes(searchTerm) ||
              filTreeRange.strttreeNum.includes(searchTerm) ||
              filterTreeRange.tree.includes(searchTerm))
        return filTreeRange;
      });

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

1 Ответ

1 голос
/ 14 мая 2019

Ваша проблема в следующих строках:

filterTreeRange.treeRanges = filterTreeRange.treeRanges.filter(...);

и

filTreeRange.treeregistered = filTreeRange.treeregistered.filter(...);

Вы изменяете свойства treeRanges и treeregistered вместо возврата измененной копии. сделать Object.assign, чтобы переопределить эти свойства, оставив при этом остальные нетронутыми.

обратите внимание, что Object.assign делает только поверхностную копию, так что вы в конечном итоге изменили исходные объекты.

вот полностью рабочая демонстрация:

const data = [{
  tree: "17200",
  treeRanges: [
    {
      id: 134055,
      strttreeNum: "5308550000000000000",
      endngtreeNum: "5308559999999999999",
      treeregistered: [
        {
          id: 9,
          branch: "12345678989895559"
        },
        {
          id: 10,
          branch: "78912349494945449"
        }
      ]
    },
    {
      id: "23175",
      strttreeNum: "1234309999999999999",
      endngtreeNum: "3466309999999999999",
      treeregistered: [
        {
          id: 14,
          branch: "5500001231234234"
        },
        {
          id: 15,
          branch: "5598761234444234"
        }
      ]
    }
  ]
}];

const treeRegisteredIncludes = searchTerm => treereg => treereg.branch.includes(searchTerm)
const treeRangesIncludes = searchTerm => treeinRange =>
    treeinRange.strttreeNum.includes(searchTerm) ||
    treeinRange.endngtreeNum.includes(searchTerm) ||
    treeinRange.treeregistered.some(treeRegisteredIncludes(searchTerm))
const itemIncludes = searchTerm => item => 
    item.tree.includes(searchTerm) ||
    item.treeRanges.some(treeRangesIncludes)

const filterByTerm = (treeRange, searchTerm) => !searchTerm ? treeRange :
    treeRange.filter(itemIncludes(searchTerm))
    .map(filterTreeRange =>
      Object.assign({}, filterTreeRange, {
        treeRanges: filterTreeRange.treeRanges
          .filter(treeRangesIncludes(searchTerm))
          .map(filTreeRange =>
            Object.assign({}, filTreeRange, {
              treeregistered: filTreeRange.treeregistered.filter(treeRegisteredIncludes(searchTerm))
            })
          )
      })
    );


console.log({
  filteredBySearchTerm: filterByTerm(data, "444"),
  original: data
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...