0

I can't figure it out how to 'unflat' the object below.

The criteria for the parent > child relationship is the number property, like so: 1 (parent) > 1.1 (child)

It's parcially correct. The .map() end up repeating items that were already in the theirs parent objects.

const arr = [
  { name: 'task a', number: '1' },
  { name: 'task b', number: '1.1'},
  { name: 'task c', number: '1.2' },
  { name: 'task d', number: '2' },
  { name: 'task e', number: '2.1' },
  { name: 'task f', number: '2.1.1' }
];

const output = arr.map((element) => {
  const re = new RegExp(`^(${element.number}\.)\\d$`)
  element.subRows = arr.filter((e) => {
    return e.number.match(re)
  })
  return element
})

output.forEach((x) => {
  console.log(x)
})

Expected output:

const data = [
  {
    name: 'task a',
    number: '1',
    subRows: [
      {
        name: 'task b',
        number: '1.1',
        subRows: []
      },
      {
        name: 'task c',
        number: '1.2',
        subRows: []

      }
    ]
  },
  {
    name: 'task d',
    number: '2',
    subRows: [
      {
        name: 'task e',
        number: '2.1',
        subRows: [
          {
            name: 'task f',
            number: '2.1.1',
            subRows: []
          }
        ]
      },
    ]
  },
];
1
  • You're code only creates the second level, it doesn't recurse. A better approach would be to use element.number.split('.') and then use something like stackoverflow.com/questions/34054601/… Commented Aug 31, 2022 at 0:39

1 Answer 1

0

I'd first do a sort to ensure a preorder traversal of the final tree, then do a reduce from left to construct it. Normally, just knowing the preorder traversal won't be sufficient to construct a tree but here we also know the depths of the nodes so it is possible.

const arr = [
      { name: 'task a', number: '1' },
      { name: 'task b', number: '1.1'},
      { name: 'task c', number: '1.2' },
      { name: 'task g', number: '1.1.1'},
      { name: 'task d', number: '2' },
      { name: 'task e', number: '2.1' },
      { name: 'task f', number: '2.1.1' }
    ];

let tree = arr.sort((x,y) => x.number.localeCompare(y.number)).reduce((acc, curr) => {
    let currDepth = 0;
    let targetDepth = Math.floor((curr.number.length-1)/2);
    let obj = acc;
    while (currDepth <= targetDepth) {
        if (currDepth == targetDepth)
            obj.subRows.push({ name : curr.name, number : curr.number, subRows : [] });
        else
            obj = obj.subRows.at(-1);
        currDepth++;
    }
    return acc;
}, { subRows : []})

console.log(tree.subRows)

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

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.