2

I'm trying to convert a flat array of objects coming from my database, to feed to react-table which needs a nested structure to be able to manage expandable sub rows.

I've made a CodeSandbox which is pretty self-explanatory :

https://codesandbox.io/s/tender-chatterjee-kdssi?file=/src/App.js

Basically, my original data is structured like so:

  [
    {
      code: "A0",
      parent: ""
    },
    {
      code: "A01",
      parent: "A0"
    },
    {
      code: "A011",
      parent: "A01"
    },
    {
      code: "B0",
      parent: ""
    },
    {
      code: "B01",
      parent: "B0"
    },
    {
      code: "B011",
      parent: "B01"
    }
  ]

And I want to convert it to this structure :

  [
    {
      code: "A0",
      parent: "",
      subRows: [
        {
          code: "A01",
          parent: "A0",
          subRows: [
            {
              code: "A011",
              parent: "A01"
            }
          ]
        }
      ]
    },
    {
      code: "B0",
      parent: "",
      subRows: [
        {
          code: "B01",
          parent: "B0",
          subRows: [
            {
              code: "B011",
              parent: "B01"
            }
          ]
        }
      ]
    }
  ]

I've tried some recursive ways of doing it, but they're leaving behind some options, so I'd gladly accept some help on this.

Thank you.

RebootGG
  • 101
  • 9

2 Answers2

5

This can be done with a fairly simple recursive method.

const mockData = [{
    code: "A0",
    parent: ""
  },
  {
    code: "A01",
    parent: "A0"
  },
  {
    code: "A011",
    parent: "A01"
  },
  {
    code: "B0",
    parent: ""
  },
  {
    code: "B01",
    parent: "B0"
  },
  {
    code: "B011",
    parent: "B01"
  }
];


const hierarchize = (parent, list) => {
  const children = list.filter(x => x.parent == parent.code);
  children.forEach(child => hierarchize(child, list));
  parent.subRows = children;
}

const topLevel = mockData.filter(x => x.parent == "");
topLevel.forEach(top => hierarchize(top, mockData));

console.log(topLevel);
Jamiec
  • 133,658
  • 13
  • 134
  • 193
  • 1
    Is it that bad ? My question was closed because of a duplicate, but neither of the answer in the original topic was as good and simple as this one, IMO. The first and accepted answer does not work unless they are already sorted. The second one uses an external library (underscore) when native JS is now perfectly capable to do this. – RebootGG Jun 10 '21 at 08:39
  • 1
    @RebootGG no it's not. It is true this question has been asked hundreds of times, but some people are just obsessive about linking a (somewhat) duplicate instead of taking 2 minutes to write some code. I like writing code, and less like finding a (somewhat) duplicate. Glad I could help you. – Jamiec Jun 10 '21 at 08:45
-2

I think React can use rxjs right??? I think groupBy will do the great job on this. https://www.learnrxjs.io/learn-rxjs/operators/transformation/groupby

  • 3
    See [this question](https://meta.stackexchange.com/questions/225370/your-answer-is-in-another-castle-when-is-an-answer-not-an-answer) for why link-only answers are considered bad. – Jamiec Jun 10 '21 at 08:10
  • I would like a solution without having to load an external library, but i'll give it a look, thanks – RebootGG Jun 10 '21 at 08:11