Greg Forel
Greg Forel

Reputation: 2579

Filtering out objects of a deeply nested data structure in Typescript / Javascript

I want to filter out of a deeply nested data structure all the objects that match a rule. I know there are similar examples to delete a particular key of nested object, but I haven't been able to implement the solutions. The data structure will never be infinite, but it can be very deep (more than 10 levels)

Here are the types:

    export type DataStructure = Entry[]

    export interface Entry {
        id: string
        text: string
        type: 1 | 2
        children?: Entry[]
    }

So an entry array could be:

[
  {
    id: "1",
    type: 1,
    text: "Node 1",
    children: [
      {
        id: "1.1",
        type: 1,
        text: "Node 1.1",       
        children: [
          {
            id: "1.1.1",            
            type: 2,
            text: "Node 1.1.1",
            children: []
          }
        ],        
      },
      {
        id: "1.2",
        type: 1,
        text: "Node 1.2",
        children: [
          {
            id: "1.2.1",
            type: 2,
            text: "Node 1.2.1",
            children: [],
          },
          {
            id: "1.2.2",
            type: 1,
            text: "Node 1.2.2",
            children: [],
          }
        ]        
      }
    ]
  }
]

The expected output array, provided the rule type !== 2 would be:

[
  {
    id: "1",
    type: 1,
    text: "Node 1",
    children: [      
      {
        id: "1.2",
        type: 1,
        text: "Node 1.2",
        children: [          
          {
            id: "1.2.2",
            type: 1,
            text: "Node 1.2.2",
            children: [],
          }
        ]        
      }
    ]
  }
]

I haven't been able to implement recursion to do it, the arrays keep showing all the entries I don't mind using lodash if there is a built-in function. Thanks!

Upvotes: 1

Views: 1379

Answers (1)

StepUp
StepUp

Reputation: 38209

If you want to filter based on type:

function test() {
      const test = [
        {
          id: "1",
          type: 1,
          text: "Node 1",
          children: [
            {
              id: "1.1",
              type: 1,
              text: "Node 1.1",
              children: [
                {
                  id: "1.1.1",
                  type: 1,
                  text: "Node 1.1.1",
                  children: []
                }
              ],
            },
            {
              id: "1.2",
              type: 2,
              text: "Node 1.2",
              children: [
                {
                  id: "1.2.1",
                  type: 2,
                  text: "Node 1.2.1",
                  children: [],
                },
                {
                  id: "1.2.2",
                  type: 2,
                  text: "Node 1.2.2",
                  children: [],
                }
              ]
            }
          ]
        }
      ];

      console.log(JSON.stringify(filterData(test, 2), 0, 4))

      console.log('test: ', test);

}

and filter method:

function filterData(data, type) {
    var r = data.filter(function(o) {
      if (o.children)
        o.children = filterData(o.children, type);
      return o.type != type
    })
    return r;
}

Upvotes: 2

Related Questions