首页 > 解决方案 > 在 Object.Assign 之后搜索过滤器嵌套数组得到修改后的原始数组

问题描述

尝试基于数字在 2 级嵌套数组上实现搜索过滤器:如果数字/数字与我的数据结构中的任何序列匹配,则结果需要与 searchcriteria 完全匹配:

我的数据结构:原始数组

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:

按搜索词搜索:4444

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

当我清除搜索时,原始嵌套的 treeregistered 数组需要重置为上面显示的原始数组。代码:

{
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 并返回过滤结果但 treeregistered 数组未根据 searchTerm 过滤时,它起作用了,我在下面添加了另一个过滤器:问题是我的原始 treeregistered 嵌套数组在我进行搜索时被修改,当我清除搜索时我没有可用的原始数组。object.assign 适用于 treeRanges 嵌套数组,但不适用于 treeregistered 嵌套数组

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;
      });

我尝试过对象方法、过滤器和映射。我知道我需要另一张地图,但我不确定如何进行深度复制,我正在做浅复制,看起来好像少了一些小东西。

标签: javascriptarraysangularecmascript-6

解决方案


你的问题出在这几行:

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

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

您正在改变treeRangesandtreeregistered属性,而不是返回修改后的副本。做一个 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
});


推荐阅读