Home > Back-end >  Is there a way to convert a flat array of objects to a nested array of objects based on same name
Is there a way to convert a flat array of objects to a nested array of objects based on same name

Time:03-09

I have an array of objects

[
    {"ID":1, "Category": "A", "SubCategory": "AA", "SubSubCategory":"AAA", "SubSubSubCategory":"foo"},
    {"ID":2, "Category": "A", "SubCategory": "AA", "SubSubCategory":"AAA", "SubSubSubCategory":"bar"},
    {"ID":3, "Category": "A", "SubCategory": "AA", "SubSubCategory":"AAB", "SubSubSubCategory":"foo"},
    {"ID":4, "Category": "A", "SubCategory": "AA", "SubSubCategory":"AAB", "SubSubSubCategory":"bar"},
    {"ID":5, "Category": "A", "SubCategory": "AB", "SubSubCategory":"ABB", "SubSubSubCategory":"foo"},
    {"ID":6, "Category": "A", "SubCategory": "AB", "SubSubCategory":"ABB", "SubSubSubCategory":"bar"},
    {"ID":7, "Category": "A", "SubCategory": "BB", "SubSubCategory":"BAA", "SubSubSubCategory":"foo"},
    {"ID":8, "Category": "A", "SubCategory": "BB", "SubSubCategory":"BAB", "SubSubSubCategory":"bar"},      
    {"ID":9, "Category": "B", "SubCategory": "AA", "SubSubCategory":"AAA", "SubSubSubCategory":"foo"},
    {"ID":10, "Category": "B", "SubCategory": "AA", "SubSubCategory":"AAA", "SubSubSubCategory":"bar"},
    {"ID":11, "Category": "B", "SubCategory": "AA", "SubSubCategory":"AAB", "SubSubSubCategory":"foo"},
    {"ID":12, "Category": "B", "SubCategory": "AA", "SubSubCategory":"AAB", "SubSubSubCategory":"bar"},
    {"ID":13, "Category": "B", "SubCategory": "AB", "SubSubCategory":"ABB", "SubSubSubCategory":"foo"},
    {"ID":14, "Category": "B", "SubCategory": "AB", "SubSubCategory":"ABB", "SubSubSubCategory":"bar"},
    {"ID":15, "Category": "B", "SubCategory": "BB", "SubSubCategory":"BAA", "SubSubSubCategory":"foo"},
    {"ID":16, "Category": "B", "SubCategory": "BB", "SubSubCategory":"BAB", "SubSubSubCategory":"bar"},
]

which i need to convert into an array of objects where objects having same category, subcategory, subsubcategory are nested, like -

[
    {
        "name":"A",
        "child": [
                    {
                        "name" : "AA",
                        "child" : [
                                    {
                                        "name" : "AAA",
                                        "child": [
                                                    {"name":"foo"},
                                                    {"name":"bar"}
                                                ]
                                    },
                                    {
                                        "name" : "AAB",
                                        "child": [
                                                    {"name":"foo"},
                                                    {"name":"bar"}
                                                ]
                                    }
                                ]
                    },
                    {
                        "name" : "AB",
                        "child" : [
                                    {
                                        "name" : "ABB",
                                        "child": [
                                                    {"name":"foo"},
                                                    {"name":"bar"}
                                                ]
                                    }
                                ]
                    },
                    {
                        "name" : "BB",
                        "child" : [
                                    {
                                        "name" : "BAA",
                                        "child": [
                                                    {"name":"foo"}
                                                ]
                                    },
                                    {
                                        "name" : "BAB",
                                        "child": [
                                                    {"name":"bar"}
                                                ]
                                    }
                                ]
                    }
                ]
    },
    {
        "name":"B",
        "child": [
                    {
                        "name" : "AA",
                        "child" : [
                                    {
                                        "name" : "AAA",
                                        "child": [
                                                    {"name":"foo"},
                                                    {"name":"bar"}
                                                ]
                                    },
                                    {
                                        "name" : "AAB",
                                        "child": [
                                                    {"name":"foo"},
                                                    {"name":"bar"}
                                                ]
                                    }
                                ]
                    },
                    {
                        "name" : "AB",
                        "child" : [
                                    {
                                        "name" : "ABB",
                                        "child": [
                                                    {"name":"foo"},
                                                    {"name":"bar"}
                                                ]
                                    }
                                ]
                    },
                    {
                        "name" : "BB",
                        "child" : [
                                    {
                                        "name" : "BAA",
                                        "child": [
                                                    {"name":"foo"}
                                                ]
                                    },
                                    {
                                        "name" : "BAB",
                                        "child": [
                                                    {"name":"bar"}
                                                ]
                                    }
                                ]
                    }
                ]
    }
] 

I am stuck here from last 2 days and not able to figure out a way to do it. I have gone through most of the similar questions but still not able to figure out a solution.

Any help would be appreciated. Thank you.

CodePudding user response:

const arr = [
  { ID: 1, Category: 'A', SubCategory: 'AA', SubSubCategory: 'AAA', SubSubSubCategory: 'foo' },
  { ID: 2, Category: 'A', SubCategory: 'AA', SubSubCategory: 'AAA', SubSubSubCategory: 'bar' },
  { ID: 3, Category: 'A', SubCategory: 'AA', SubSubCategory: 'AAB', SubSubSubCategory: 'foo' },
  { ID: 4, Category: 'A', SubCategory: 'AA', SubSubCategory: 'AAB', SubSubSubCategory: 'bar' },
  { ID: 5, Category: 'A', SubCategory: 'AB', SubSubCategory: 'ABB', SubSubSubCategory: 'foo' },
  { ID: 6, Category: 'A', SubCategory: 'AB', SubSubCategory: 'ABB', SubSubSubCategory: 'bar' },
  { ID: 7, Category: 'A', SubCategory: 'BB', SubSubCategory: 'BAA', SubSubSubCategory: 'foo' },
  { ID: 8, Category: 'A', SubCategory: 'BB', SubSubCategory: 'BAB', SubSubSubCategory: 'bar' },
  { ID: 9, Category: 'B', SubCategory: 'AA', SubSubCategory: 'AAA', SubSubSubCategory: 'foo' },
  { ID: 10, Category: 'B', SubCategory: 'AA', SubSubCategory: 'AAA', SubSubSubCategory: 'bar' },
  { ID: 11, Category: 'B', SubCategory: 'AA', SubSubCategory: 'AAB', SubSubSubCategory: 'foo' },
  { ID: 12, Category: 'B', SubCategory: 'AA', SubSubCategory: 'AAB', SubSubSubCategory: 'bar' },
  { ID: 13, Category: 'B', SubCategory: 'AB', SubSubCategory: 'ABB', SubSubSubCategory: 'foo' },
  { ID: 14, Category: 'B', SubCategory: 'AB', SubSubCategory: 'ABB', SubSubSubCategory: 'bar' },
  { ID: 15, Category: 'B', SubCategory: 'BB', SubSubCategory: 'BAA', SubSubSubCategory: 'foo' },
  { ID: 16, Category: 'B', SubCategory: 'BB', SubSubCategory: 'BAB', SubSubSubCategory: 'bar' },
];
const result = arr.reduce((acc, curr) => {
  const { Category, SubCategory, SubSubCategory, SubSubSubCategory } = curr;
  const category = acc.find(x => x.name === Category);
  if (!category) {
    acc.push({
      name: Category,
      child: [
        {
          name: SubCategory,
          child: [
            {
              name: SubSubCategory,
              child: [{ name: SubSubSubCategory }],
            },
          ],
        },
      ],
    });
  } else {
    const subCategory = category.child.find(x => x.name === SubCategory);
    if (!subCategory) {
      category.child.push({
        name: SubCategory,
        child: [
          {
            name: SubSubCategory,
            child: [{ name: SubSubSubCategory }],
          },
        ],
      });
    } else {
      const subSubCategory = subCategory.child.find(x => x.name === SubSubCategory);
      if (!subSubCategory) {
        subCategory.child.push({
          name: SubSubCategory,
          child: [{ name: SubSubSubCategory }],
        });
      } else {
        subSubCategory.child.push({ name: SubSubSubCategory });
      }
    }
  }
  return acc;
}
  , []);
console.log(JSON.stringify(result, null, 2));

CodePudding user response:

You can keep a references to different levels in one object an the values will be actual arrays from the result. Then you loop over main array and inside using reduce you also iterate over the keys that are defined in the correct order by nested level.

const data = [{"ID":1,"Category":"A","SubCategory":"AA","SubSubCategory":"AAA","SubSubSubCategory":"foo"},{"ID":2,"Category":"A","SubCategory":"AA","SubSubCategory":"AAA","SubSubSubCategory":"bar"},{"ID":3,"Category":"A","SubCategory":"AA","SubSubCategory":"AAB","SubSubSubCategory":"foo"},{"ID":4,"Category":"A","SubCategory":"AA","SubSubCategory":"AAB","SubSubSubCategory":"bar"},{"ID":5,"Category":"A","SubCategory":"AB","SubSubCategory":"ABB","SubSubSubCategory":"foo"},{"ID":6,"Category":"A","SubCategory":"AB","SubSubCategory":"ABB","SubSubSubCategory":"bar"},{"ID":7,"Category":"A","SubCategory":"BB","SubSubCategory":"BAA","SubSubSubCategory":"foo"},{"ID":8,"Category":"A","SubCategory":"BB","SubSubCategory":"BAB","SubSubSubCategory":"bar"},{"ID":9,"Category":"B","SubCategory":"AA","SubSubCategory":"AAA","SubSubSubCategory":"foo"},{"ID":10,"Category":"B","SubCategory":"AA","SubSubCategory":"AAA","SubSubSubCategory":"bar"},{"ID":11,"Category":"B","SubCategory":"AA","SubSubCategory":"AAB","SubSubSubCategory":"foo"},{"ID":12,"Category":"B","SubCategory":"AA","SubSubCategory":"AAB","SubSubSubCategory":"bar"},{"ID":13,"Category":"B","SubCategory":"AB","SubSubCategory":"ABB","SubSubSubCategory":"foo"},{"ID":14,"Category":"B","SubCategory":"AB","SubSubCategory":"ABB","SubSubSubCategory":"bar"},{"ID":15,"Category":"B","SubCategory":"BB","SubSubCategory":"BAA","SubSubSubCategory":"foo"},{"ID":16,"Category":"B","SubCategory":"BB","SubSubCategory":"BAB","SubSubSubCategory":"bar"}]

const order = ['Category', 'SubCategory', 'SubSubCategory', 'SubSubSubCategory']

function f(data) {
  const result = []
  const levels = {
    _: result
  }

  data.forEach((e) => {
    order.reduce((r, _e, i, a) => {
      const name = e[_e]
      if (!r[name]) {
        r[name] = {
          _: []
        }
        r._.push({
          name,
          child: r[name]._
        })
      }

      return r[name]
    }, levels)
  })

  return result
}

const result = f(data)

console.log(result)

  • Related