Home > Software design >  How to loop through two arrays of objects and get a new array with some data modified?
How to loop through two arrays of objects and get a new array with some data modified?

Time:07-28

How to loop through two arrays of objects and get a new array with some data modified?

Arrays:

  const products = [
    {
      brand: 'Levis',
      category: 'Jeans',
    },
    {
      brand: 'Levis',
      category: 'Jeans',
    },
    {
      brand: 'Levis',
      category: 'Tees',
    },
  ];


  const categories = [
    {
      name: 'Jeans',
    },
    {
      name: 'Tees',
    },
  ];

Need new categories array like this with new prop productCount:

  const newCategories = [
    {
      name: 'Jeans',
      productCount: 2,
    },
    {
      name: 'Tees',
      productCount: 0,
    },
  ];

I tried this way but it doesn't work:

  const newArr = categories.map((category) => {
    let count = 0;

    const index = products.findIndex((product) => category.name === product.category);

    if (index > -1) {
      return {
        ...category,
        productCount: count  ,
      };
    }

    return {
      ...category,
      productCount: 0,
    };
  });

CodePudding user response:

Increasing the count number will not in that case because it will always start with zero. Instead, you can use the filter() method to find the number of products with a specific category and assign this number to productCount attribute.

const products = [{
    brand: 'Levis',
    category: 'Jeans',
  },
  {
    brand: 'Levis',
    category: 'Jeans',
  },
  {
    brand: 'Levis',
    category: 'Tees',
  },
];


const categories = [{
    name: 'Jeans',
  },
  {
    name: 'Tees',
  },
];

const newArr = categories.map((category) => {
  const numberOfItems = products.filter((product) => category.name === product.category);

  return {
    ...category,
    productCount: numberOfItems.length,
  };
});

console.log(newArr)

CodePudding user response:

You can create an object and the transform it to array, something like this:

  const products = [
    {
      brand: "Levis",
      category: "Jeans"
    },
    {
      brand: "Levis",
      category: "Jeans"
    },
    {
      brand: "Levis",
      category: "Tees"
    }
  ];

  const categoriesObj = {};

  products.forEach(({ brand, category }) => {
    categoriesObj[category] ??= {
      name: category,
      productCount: 0
    };
      categoriesObj[category].productCount;
  });

  const newCategories = Object.values(categoriesObj);
  console.log(newCategories);

CodePudding user response:

You can use the Array#Map method and add a productCount property using the Array#filter method

const products = [{
    brand: 'Levis',
    category: 'Jeans',
  },
  {
    brand: 'Levis',
    category: 'Jeans',
  },
  {
    brand: 'Levis',
    category: 'Tees',
  },
];


const categories = [{
    name: 'Jeans',
  },
  {
    name: 'Tees',
  },
];


const newCategories = [...categories].map(category => ({
  ...category,
  productCount: products.filter(product => product.category === category.name).length
}))

console.log(newCategories)

CodePudding user response:

You could do this with Array.reduce(), incrementing the productCount for each item. This should also be efficient, requiring only one iteration of the products array.

We'd run the reduce over both arrays, ensuring that we'll end up with a productCount of zero where no products for that category exist.

const products = [ { brand: 'Levis', category: 'Jeans', }, { brand: 'Levis', category: 'Jeans', }, { brand: 'Levis', category: 'Tees', }, ];
const categories = [ { name: 'Jeans', }, { name: 'Tees', }, { name: 'Foo', } ];
  
const result = Object.values([...categories, ...products].reduce((acc, { brand, category, name }) => {
    const key = name || category;
    acc[key] = acc[key] || { name: key, productCount: 0 };
    if (category) acc[key].productCount  ;
    return acc;
}, {}));

console.log('Result:', result);
.as-console-wrapper { max-height: 100% !important; }

  • Related