如何过滤嵌套对象? ReactJS

时间:2017-11-21 08:56:28

标签: javascript reactjs filter

数据样本:

nodes:[
        {
        label:"Egor1",
        value:"Egor1",
        restorePoint:"25/10/2017 10:00:29 PM",
        vmcount:"2",
        restorePointsCount:"",
        children:[
          {label:"disk111111111111111",
          value:"disk1",
          restorePoint:"3 days ago",
          vmcount:"",
          restorePointsCount:"11",
        },
        {label:"disk22222222222222",
        value:"disk2",
        name:"jobname2",
        restorePoint:"4 days ago",
        vmcount:"",
        restorePointsCount:"11"},
        {label:"disk555",
        value:"disk552",
        name:"jobnam555e2",
        restorePoint:"4 days ago",
        vmcount:"",
        restorePointsCount:"11"}
      ]}
      ,

      {
        label:"Egor12",
        value:"Egor12",
        restorePoint:"25/10/2017 10:00:29 PM",
        vmcount:"22",
        restorePointsCount:"",
        children:[
          {label:"disk111111111111111",
          value:"disk1",
          restorePoint:"2 days ago",
          vmcount:"",
          restorePointsCount:"12",
        },
        {label:"disk22222222222222",
        value:"disk2",
        name:"jobname2",
        restorePoint:"restorepoint4",
        vmcount:"",
        restorePointsCount:"12",}
      ]},


      ],

尝试下一步:

filter(e) {
    var value = e.target.value;
    this.setState({filterval: value})
    this.setState({
      filteredItems: !value
        ? false
        : this.state.nodes.filter(function (item) {
          return 
          item.children.value.toLowerCase().indexOf(value.toLowerCase()) !== -1;
        })
    })
  }

但是过滤器想要工作,如何通过嵌套对象进行过滤?找不到任何例外。可以用_lodash吗?

例如我搜索           标签:“disk111111111111111

结果必须是这样的数组:

{
        label:"Egor1",
        value:"Egor1",
        restorePoint:"25/10/2017 10:00:29 PM",
        vmcount:"2",
        restorePointsCount:"",
        children:[
          {label:"disk111111111111111",
          value:"disk1",
          restorePoint:"3 days ago",
          vmcount:"",
          restorePointsCount:"11",
        },

所以它必须不仅返回我搜索的元素,它必须返回与父母一起的孩子。

3 个答案:

答案 0 :(得分:0)

您的item.children是一个数组。如果其中只有一个项目,那么您可以item.children[0]。否则,你必须循环它以检查你的状况。

答案 1 :(得分:0)

您可以混合使用mapfilter。第一个映射每个项目并过滤其子项(根据您的需要),第二个项目过滤具有children.length > 0

的项目



const nodes = [
  {
    label: 'Egor1',
    value: 'Egor1',
    restorePoint: '25/10/2017 10:00:29 PM',
    vmcount: '2',
    restorePointsCount: '',
    children: [
      {
        label: 'disk111111111111111',
        value: 'disk1',
        restorePoint: '3 days ago',
        vmcount: '',
        restorePointsCount: '11',
      },
      {
        label: 'disk22222222222222',
        value: 'disk2',
        name: 'jobname2',
        restorePoint: '4 days ago',
        vmcount: '',
        restorePointsCount: '11',
      },
      {
        label: 'disk555',
        value: 'disk552',
        name: 'jobnam555e2',
        restorePoint: '4 days ago',
        vmcount: '',
        restorePointsCount: '11',
      },
    ],
  },
  {
    label: 'Egor12',
    value: 'Egor12',
    restorePoint: '25/10/2017 10:00:29 PM',
    vmcount: '22',
    restorePointsCount: '',
    children: [
      {
        label: 'disk111111111111111',
        value: 'disk1',
        restorePoint: '2 days ago',
        vmcount: '',
        restorePointsCount: '12',
      },
      {
        label: 'disk22222222222222',
        value: 'disk2',
        name: 'jobname2',
        restorePoint: 'restorepoint4',
        vmcount: '',
        restorePointsCount: '12',
      },
    ],
  },
]

const value = 'disk552'

const result = nodes
  .map(item => ({
    ...item,
    children: item.children
      .filter(child => child.value.includes(value.toLowerCase()))
  }))
  .filter(item => item.children.length > 0)
  
console.log(result)




答案 2 :(得分:0)

您可以filter超过nodes,然后测试children.value以查看要保留的节点。

const FakeReact = {
  setState(newState) {
    this.state = Object.assign({}, this.state, newState)
  },
  state: {
    nodes: [
      { value: "Egor1", children: [{ value: "disk1" }, { value: "disk2" }] },
      { value: "Egor2", children: [{ value: "disk3" }, { value: "disk4" }] },
    ]
  }
}

const fakeEvent = { target: { value: 'disk1' }}

function filter(e) {
  const value = e.target.value;
  const regex = new RegExp('.*' + value + '.*', 'gi')
  this.setState({
    filterval: value, // may as well only make one call to set state
    filteredItems: (!value)
      ? [] // try to keep the same type for the false value
      : this.state.nodes.filter(
        // filter the node
        node =>
          node.children.find(
            // check if the child value matches the input value
            // if it does the node will be returned to filteredItems
            child => regex.test(child.value)
          )
        )
  })
}

// call filter with the FakeReact as the context and a fake event
filter.call(FakeReact, fakeEvent)

console.log('nodes', FakeReact.state.nodes)
console.log('filteredItems', FakeReact.state.filteredItems)
<script src="https://codepen.io/synthet1c/pen/KyQQmL.js?theme=onedark"></script>