kaushal
kaushal

Reputation: 15

Create nested array of object upto a limit

I have an array of objects like this
    const ticketsData = [
            { id: 1, title: 'parent', parent: 0, url: '' },
            { id: 2, title: 'parent', parent: 0, url: '' },
            { id: 3, title: 'child', parent: 1, url: '' },
            { id: 4, title: 'sub child', parent: 3, url: '' },
            { id: 5, title: 'sub sub child', parent: 4, url: '' },
            { id: 6, title: 'sub sub sub child', parent: 5, url: '' },
            { id: 10, title: 'sub sub child 2', parent: 4, url: '' },
            { id: 13, title: 'sub child 2', parent: 3, url: '' },
            { id: 14, title: 'child', parent: 2, url: '' },
            { id: 7, title: 'sub sub sub child', parent: 5, url: '' },
            { id: 8, title: 'sub sub sub child', parent: 5, url: '' },
            { id: 9, title: 'sub sub sub child', parent: 5, url: '' },
            { id: 11, title: 'sub sub child 3', parent: 4, url: '' },
            { id: 12, title: 'sub sub child 4', parent: 4, url: '' }
          ];

and I want to create a nested array of object upto a limit, say 10. So when the count reduces to zero it should return the array till that child/parent.

> This is my expected Output:

    [{ id: 1, title: 'parent', parent: 0, url: '', children: [
{ id: 3, title: 'child', parent: 1, url: '', children:[
{ id: 4, title: 'sub child', parent: 3, url: '', children:[
{ id: 5, title: 'sub sub child', parent: 4, url: '' , children:[
{ id: 6, title: 'sub sub sub child', parent: 5, url: '', children:[] },
{ id: 7, title: 'sub sub sub child', parent: 5, url: '', children:[] },
{ id: 8, title: 'sub sub sub child', parent: 5, url: '', children:[] },
{ id: 9, title: 'sub sub sub child', parent: 5, url: '', children:[] }
]},
{ id: 10, title: 'sub sub child 2', parent: 4, url: '', children:[] },
{ id: 11, title: 'sub sub child 3', parent: 4, url: '', children:[] }
] }
] }
] }]

I tried this but getting all the objects in separate array.

     const createTicketTree = (tickets, count) => {
        let ticketObj = {};
        let ticketHierarchy = []
        tickets.map( ticket => {
          ticketObj[ticket.id] = { ...ticket, children: [] };
            if(ticket.parent && count && count--) {
              ticketObj[ticket.parent].children.push(ticketObj[ticket.id]) 
             }
            else { 
            ticketHierarchy.push(ticketObj[ticket.id]) 
            }
        });
        return ticketHierarchy;
    };

This is how I am calling the function to get the nested parent-children relation upto 10. Is there any lodash/underscore implementation to acheive this? Any help would be appreciated

    createTicketTree(ticketsData, 10);

Upvotes: 0

Views: 339

Answers (2)

Nenad Vracar
Nenad Vracar

Reputation: 122047

You could use recursive approach with reduce method and keep count of added elements inside one variable and check if the count is less then 0 to stop adding elements to array.

const ticketsData = [{"id":1,"title":"parent","parent":0,"url":""},{"id":2,"title":"parent","parent":0,"url":""},{"id":3,"title":"child","parent":1,"url":""},{"id":4,"title":"sub child","parent":3,"url":""},{"id":5,"title":"sub sub child","parent":4,"url":""},{"id":6,"title":"sub sub sub child","parent":5,"url":""},{"id":10,"title":"sub sub child 2","parent":4,"url":""},{"id":13,"title":"sub child 2","parent":3,"url":""},{"id":14,"title":"child","parent":2,"url":""},{"id":7,"title":"sub sub sub child","parent":5,"url":""},{"id":8,"title":"sub sub sub child","parent":5,"url":""},{"id":9,"title":"sub sub sub child","parent":5,"url":""},{"id":11,"title":"sub sub child 3","parent":4,"url":""},{"id":12,"title":"sub sub child 4","parent":4,"url":""}]

let count = 10;

function createTicketTree(data, pid = 0) {
  return data.reduce((r, e) => {
    if (e.parent === pid && count > 0) {
      count--
      const o = { ...e }
      const c = createTicketTree(data, e.id);
      if (c.length) o.children = c;
      r.push(o)
    }

    return r;
  }, [])
}

const result = createTicketTree(ticketsData);
console.log(result)

Upvotes: 1

repinuj
repinuj

Reputation: 26

I don't think the if condition is what you're looking for. count isn't getting modified or saved anywhere. I would modify the if statement to check for the length of the parent ticket's children, compared to the count:

if(ticket.parent && ticketObj[ticket.parent].children.length < count)

However, I am confused about what the end result is you're looking for, and how you're counting the nested objects in the children list.

Upvotes: 0

Related Questions