0

Data sample:

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",}
      ]},


      ],

Try to do next:

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

But filter wants work, how filter by nested objects? Can't find any exmaple. it possible to do with _lodash?

For example I search label:"disk111111111111111

In result must be array like this :

{
        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",
        },

So it must return not only elements, that I search, it must return childrens with parents.

4
  • Why do you call this.setState two times in a row ? Commented Nov 21, 2017 at 8:58
  • because first goes to input, second goes to filtered array Commented Nov 21, 2017 at 8:59
  • what do you want to filter on Commented Nov 21, 2017 at 9:03
  • all childrens, there can be many childrens Commented Nov 21, 2017 at 9:07

3 Answers 3

2

You can mix map and filter. First one maps every item and filter its children (according your needs) and the second one filters items which has 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)

Sign up to request clarification or add additional context in comments.

2 Comments

It filter only correct by parents, for example I search child with value disk552, and it return 3 elements that included in this parent
@egorchik I've just updated my answer. Please check again :)
0

Your item.children is an array. If there is only one item in it, then you can do item.children[0]. Otherwise, you have to loop it too to check your condition.

3 Comments

then as I said, you have to loop through them as well.
Please add full input JSON to question and output your are expecting.
added, please see
0

You could filter over the nodes then test the children.value to see which nodes to keep.

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>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.