'Why does my condition for my .push() in JSX return double values?

I am starting with a data file of objects in random order. They are of two types: Category and SubCategory.

I have managed to separate them and re-arrange them in order. But although each category exists only once in the original array, they are coming in in duplicates in the new array.

I am a newbie, so it has taken me a while to understand the logic, but I can't find the reason why the duplicates. Can you help me understand where/why this is happening?

Sample Data

[
  {
    "_id": "6181840f60c425f76e57b56c",
    "name": "Cakes ",
    "slug": "deli-sweet-cakes",
    "parent_id": "6181841060c425f76e57b5b3",
    "product_skus": [],
    "rank": 2
  },
  {
    "_id": "6181841060c425f76e57b57f",
    "name": "Soda Water",
    "slug": "beer-cider-sodas",
    "parent_id": "6181841060c425f76e57b604",
    "product_skus": [],
    "rank": 3
  },
 {
    "_id": "6181841060c425f76e57b604",
    "name": "Beers & Ciders",
    "slug": "beers-and-ciders",
    "product_skus": [],
    "rank": 21
  }]  

if an object doesn't have "parent_id" then it is a category.

import data from "./data.json";

function App() {
  // Find non-special category objects ...
  let categories = data.filter((obj) => {
    return !obj.parent_id && !obj.is_special;
  });
  // Find non-special subcategory objects
  let subCategories = data.filter((obj) => {
    return obj.parent_id && !obj.is_special;
  });

  // create an empty container for them
  let orderedCategories = [];

  // re-arrange them
  categories.forEach((category) => {
    orderedCategories.push(category);
    if (!category.subCategories) {
      category.subCategories = [];
    }
    subCategories.forEach((subCategory) => {
      if (category._id === subCategory.parent_id) {
        category.subCategories.push(subCategory);
      }
    });
  });
  console.log(orderedCategories);
  return null;
}

The resulting data is as I expected, except the list of sub categories repeats itself once more.

name: "Beers and Ciders"
product_skus: []
rank: 21
slug: "beers-and-ciders"
subCategories: (6)

        0: {_id: '6181841060c425f76e57b57f', name: 'Hard Seltzer' ... 
        1: {_id: '6181841060c425f76e57b58f', name: 'Beer' ... 
        2: {_id: '6181841060c425f76e57b59f', name: 'Cider' ... 
        3: {_id: '6181841060c425f76e57b57f', name: 'Hard Seltzer' ... 
        4: {_id: '6181841060c425f76e57b58f', name: 'Ber' ... 
        5: {_id: '6181841060c425f76e57b59f', name: 'Cider' ... 



Solution 1:[1]

I realise now that there was an error in the syntax.

In my original code, I run two separate loops:

// loop one:
  categories.forEach((category) => {
    orderedCategories.push(category);
    if (!category.subCategories) {
      category.subCategories = [];
    }
//loop two:
    subCategories.forEach((subCategory) => {
      if (category._id === subCategory.parent_id) {
        category.subCategories.push(subCategory);
      }
    });

Instead, it should be a single loop with a nested loop.

categories.forEach((category) => {
    orderedCategories.push(category);
    if (!category.subCategories) {
      category.subCategories = [];
      subCategories.forEach((subCategory) => {
        if (category._id === subCategory.parent_id) {
          category.subCategories.push(subCategory);
        }
      });
    }
  });

The original code returns the data twice. Nesting the loops returns correctly, only once.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 cordovez