0

I have an array of values and I want to convert them into nested objects if the category i.e 1st element exists then the next subcategories are pushed in this. Can we achieve this, I am beginner please help

for example:

    const newCat = [
                     [
                        "Grocery", // category
                        "Food & Drink", // sub-category
                        "Snacks, Crisps and Sweets", // sub-sub-category
                    ],
                    [
                        "Grocery",
                        "Canned, Dry & Packaged Food",
                        "Pickled Foods",
                    ],
                    [
                        "Grocery",
                        "Food & Drink",
                    ],
                    [
                        "Grocery",
                        "Food & Drink",
                        "Nuts, Dates & Dried Fruits",
                    ],
                    [
                        "Grocery",
                        "World Specialities",
                        "India",
                    ],

                  ]
OUTPUT -
[
    {
    CategoryName: "Grocery",
    SubCategories: [
      {
        CategoryName: "Food & Drink",
        SubCategories: [
          {
            CategoryName: "Snacks, Crisps, and Sweets",
          },
        ],
      },
      {
        CategoryName: "Canned, Dry & Packaged Food",
        SubCategories: [
          {
            CategoryName: "Pickled Foods",
          },

        ],

      },
    ],
  }
]

2 Answers 2

1

function flatArray(arr) {
  const result = [];
  for (let item of arr) {
    const [c1, c2, c3] = item;
    const findC1 = result.find(c => c.categoryName === c1);
    if (findC1) {
      if (!c2) {
        continue;
      }
      const findC2 = findC1.subCategorys.find(c => c.categoryName === c2);
      if (findC2) {
        if (!c3) {
          continue;
        }
        findC2.subCategorys.push(c3);
      } else {
        findC1.subCategorys.push({
          categoryName: c2,
          subCategorys: [c3]
        });
      }
    } else {
      result.push({
        categoryName: c1,
        subCategorys: [
          {
            categoryName: c2,
            subCategorys: [c3]
          }
        ]
      })
    }
  }  
  
  return result;
}


// Test case
const newCat = [
   [
      "Grocery", // category
      "Food & Drink", // sub-category
      "Snacks, Crisps and Sweets", // sub-sub-category
  ],
  [
      "Grocery",
      "Canned, Dry & Packaged Food",
      "Pickled Foods",
  ],
  [
      "Grocery",
      "Food & Drink",
  ],
  [
      "Grocery",
      "Food & Drink",
      "Nuts, Dates & Dried Fruits",
  ],
  [
      "Grocery",
      "World Specialities",
      "India",
  ],

];

console.log(flatArray(newCat));

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

Comments

1

const newCat = [
  [
    "Grocery", // category
    "Food & Drink", // sub-category
    "Snacks, Crisps and Sweets", // sub-sub-category
  ],
  [
    "Grocery",
    "Canned, Dry & Packaged Food",
    "Pickled Foods",
  ],
  [
    "Grocery",
    "Food & Drink",
  ],
  [
    "Grocery",
    "Food & Drink",
    "Nuts, Dates & Dried Fruits",
  ],
  [
    "Grocery",
    "World Specialities",
    "India",
  ],
  ["Electronics", "Speakers", "Bluetooth Speakers", "JBL", ],
]

const output = []

newCat.forEach((e) => {
  let indexofCategory = output.findIndex((category) => category.CategoryName === e[0]);
  if (indexofCategory === -1) {
    output.push({
      CategoryName: e[0],
      SubCategories: []
    })
    indexofCategory = output.length - 1;
  }
  if (e[1]) {
    let indexofSubcategory = output[indexofCategory].SubCategories.findIndex((category) => category.CategoryName === e[1]);
    if (indexofSubcategory === -1) {
      output[indexofCategory].SubCategories.push({
        CategoryName: e[1],
        SubCategories: []
      })
      indexofSubcategory = output[indexofCategory].SubCategories.length - 1;
    }
    if (e[2]) {
      let indexofSubSubcategory = output[indexofCategory].SubCategories[indexofSubcategory].SubCategories.findIndex((category) => category.CategoryName === e[2]);
      if (indexofSubSubcategory === -1) {
        output[indexofCategory].SubCategories[indexofSubcategory].SubCategories.push({
          CategoryName: e[2],
          SubCategories: [],
        })
        indexofSubSubcategory = output[indexofCategory].SubCategories[indexofSubcategory].SubCategories.length - 1;
      }
      if (e[3]) {
        const indexofSubSubSubcategory = output[indexofCategory].SubCategories[indexofSubcategory].SubCategories[indexofSubSubcategory].SubCategories.findIndex((category) => category.CategoryName === e[3]);
        if (indexofSubSubSubcategory === -1) output[indexofCategory].SubCategories[indexofSubcategory].SubCategories[indexofSubSubcategory].SubCategories.push({
          CategoryName: e[3]
        })
      }
    }
  }
});

console.log(output)

2 Comments

just one problem here I am facing that there can be 4th level also like [ "Electronics", "Speakers", "Bluetooth Speakers", "JBL", ], can you please let me know how to do this
@RaviVishwakarma I updated my code. The overall rule is very simple - for every level, you should add another part of code where you check if a specific item at a specific level exists and if it does not exists add it. Although I believe it can be done more 'abstract' and there is a lot of room for improvement.

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.