1

I have two arrays, one for categories and other for products. Products contain multiple categories as a comma-separated string. Now I want to match a particular category and add the matched product to an array to each category.

I want to match the category to product_category.

Here are the arrays

Products

[
    {
        "id": 1,
        "product_title": "Product 1",
        "product_size": null,
        "product_author": 5,
        "description": "Test Description",
        "product_category": "Shirts,Pents,Salwar",
        "createdAt": "2020-02-08T11:42:15.000Z",
        "updatedAt": "2020-02-08T11:42:15.000Z"
    },
    {
        "id": 4,
        "product_title": "Product 2",
        "product_size": null,
        "product_author": 5,
        "description": "Test Description",
        "product_category": "Pents,Salwar",
        "createdAt": "2020-02-08T11:42:15.000Z",
        "updatedAt": "2020-02-10T07:08:23.000Z"
    }
]

Categories

[
    {
        "id": 1,
        "category_name": "Shirts",
        "createdAt": "2020-02-08T04:59:59.000Z",
        "updatedAt": "2020-02-10T06:50:05.000Z"
    },
    {
        "id": 9,
        "category_name": "Pents",
        "createdAt": "2020-02-08T04:59:59.000Z",
        "updatedAt": "2020-02-10T06:50:05.000Z"
    }
]

Code that I try but not working

    this.categories.forEach(cat => {
      this.products.filter(prod => {
        if (prod.product_category.split(',').indexOf(cat.category_name) !== -1) {
          this.categories.push(prod);
        }
      });
    });

Please help me to solve this issue.

Any solution appreciated!

4
  • 2
    what is the expected output? "match the category" does not seem descriptive enough to me Commented Feb 10, 2020 at 7:41
  • 1
    filter expects a boolean Commented Feb 10, 2020 at 7:42
  • Do you want to append to each category products that belong to this category? Commented Feb 10, 2020 at 7:43
  • Yes @niklaz this is what i trying to say and sorry if you not understand Commented Feb 10, 2020 at 7:44

8 Answers 8

3

You could use .map() on categories to add a products property to it. This property will be the result of a .filter() on the products.

const categoriesWithProducts = categories.map(cat => {
  return {
    ...cat,
    products: products.filter(prod => {
      return prod.product_category.split(',').includes(cat.category_name);
    })
  };
});
``
Sign up to request clarification or add additional context in comments.

1 Comment

You can use Array.includes() to get rid of unnecessary index checking: prod.product_category.split(',').includes(cat.category_name)
0

One of the approaches is to create a new array where you would push products mapped to specific categories:

var products = [
    {
        "id": 1,
        "product_title": "Product 1",
        "product_size": null,
        "product_author": 5,
        "description": "Test Description",
        "product_category": "Shirts,Pents,Salwar",
        "createdAt": "2020-02-08T11:42:15.000Z",
        "updatedAt": "2020-02-08T11:42:15.000Z"
    },
    {
        "id": 4,
        "product_title": "Product 2",
        "product_size": null,
        "product_author": 5,
        "description": "Test Description",
        "product_category": "Pents,Salwar",
        "createdAt": "2020-02-08T11:42:15.000Z",
        "updatedAt": "2020-02-10T07:08:23.000Z"
    }
];

var categories = [
    {
        "id": 1,
        "category_name": "Shirts",
        "createdAt": "2020-02-08T04:59:59.000Z",
        "updatedAt": "2020-02-10T06:50:05.000Z"
    },
    {
        "id": 9,
        "category_name": "Pents",
        "createdAt": "2020-02-08T04:59:59.000Z",
        "updatedAt": "2020-02-10T06:50:05.000Z"
    }
]
var productCategories = [];
categories.forEach((cat)=> {
var productCategory = {};
productCategory.category = cat;
productCategory.products = [];
products.forEach(prod => { 
        if (prod.product_category.indexOf(cat.category_name) !== -1) {
          productCategory.products.push(prod);
        }
      });

productCategories.push(productCategory);
console.log(productCategories);
});

Comments

0

You do not need filter(), you can use another forEach() with includes() and Object.assign():

var products = [
    {
        "id": 1,
        "product_title": "Product 1",
        "product_size": null,
        "product_author": 5,
        "description": "Test Description",
        "product_category": "Shirts,Pents,Salwar",
        "createdAt": "2020-02-08T11:42:15.000Z",
        "updatedAt": "2020-02-08T11:42:15.000Z"
    },
    {
        "id": 4,
        "product_title": "Product 2",
        "product_size": null,
        "product_author": 5,
        "description": "Test Description",
        "product_category": "Pents,Salwar",
        "createdAt": "2020-02-08T11:42:15.000Z",
        "updatedAt": "2020-02-10T07:08:23.000Z"
    }
];
var categories = [
    {
        "id": 1,
        "category_name": "Shirts",
        "createdAt": "2020-02-08T04:59:59.000Z",
        "updatedAt": "2020-02-10T06:50:05.000Z"
    },
    {
        "id": 9,
        "category_name": "Pents",
        "createdAt": "2020-02-08T04:59:59.000Z",
        "updatedAt": "2020-02-10T06:50:05.000Z"
    }
]

categories.forEach((cat,i) => {
  products.forEach(prod => {
    if (prod.product_category.split(',').includes(cat.category_name)) {
      Object.assign(categories[i], prod);
    }
  });
});
console.log(categories);

Comments

0

You can use Array#filter to filter products on catagory names using Array#some

let products = [{"id":1,"product_title":"Product 1","product_size":null,"product_author":5,"description":"Test Description","product_category":"Shirts,Pents,Salwar","createdAt":"2020-02-08T11:42:15.000Z","updatedAt":"2020-02-08T11:42:15.000Z"},{"id":4,"product_title":"Product 2","product_size":null,"product_author":5,"description":"Test Description","product_category":"Pents,Salwar","createdAt":"2020-02-08T11:42:15.000Z","updatedAt":"2020-02-10T07:08:23.000Z"}]

let catagories = [{"id":1,"category_name":"Shirts","createdAt":"2020-02-08T04:59:59.000Z","updatedAt":"2020-02-10T06:50:05.000Z"},{"id":9,"category_name":"Pents","createdAt":"2020-02-08T04:59:59.000Z","updatedAt":"2020-02-10T06:50:05.000Z"}]

let catagoryNames =  new Set(catagories.map(e => e.category_name));

let filtered = [...products].filter(e => e.product_category.split(',').some(cat => catagoryNames.has(cat)));
console.log(filtered)

Comments

0

Try this

categories.forEach(function(c){
    c.products=products.filter(function(p){
        var reg=new RegExp(c.category_name,'gi');
        return reg.test(p.product_category)
    })

})

Without Regex

categories.forEach(function(c){
    c.products=products.filter(function(p){

        return (p.product_category.split(',').indexOf(c.category_name)!==-1)
    })

})

You will get the products inside each category

Fiddle here

3 Comments

products are not defined
Yes you r right in your way, but i do this in angular
Then i think you can add a property products while defining categories
0

Try this code.I hope it will helps you.

product = [
    {
        "id": 1,
        "product_title": "Product 1",
        "product_size": null,
        "product_author": 5,
        "description": "Test Description",
        "product_category": "Shirts,Pents,Salwar",
        "createdAt": "2020-02-08T11:42:15.000Z",
        "updatedAt": "2020-02-08T11:42:15.000Z"
    },
    {
        "id": 4,
        "product_title": "Product 2",
        "product_size": null,
        "product_author": 5,
        "description": "Test Description",
        "product_category": "Pents,Salwar",
        "createdAt": "2020-02-08T11:42:15.000Z",
        "updatedAt": "2020-02-10T07:08:23.000Z"
    }
]
  categories=[
    {
        "id": 1,
        "category_name": "Shirts",
        "createdAt": "2020-02-08T04:59:59.000Z",
        "updatedAt": "2020-02-10T06:50:05.000Z",
    },
    {
        "id": 9,
        "category_name": "Pents",
        "createdAt": "2020-02-08T04:59:59.000Z",
        "updatedAt": "2020-02-10T06:50:05.000Z",
    }
]


   this.categories.forEach(cat => {
     cat['product'] = []
      this.product.filter(prod => {
        if (prod.product_category.split(',').indexOf(cat.category_name) !== -1) {
         cat['product'].push(prod);
        }
      });
    });
     console.log(this.categories)

Comments

0

You can easily loop through all categories and then loop throgh all products. For each product check if category name is present and if so add product to category products:

    this.categories.forEach(cat => {
      cat.products = [];

      this.products.forEach(prod => {
        if (prod.product_category.split(',').indexOf(cat.category_name) !== -1) {
          cat.products.push(prod);
        }
      });
    });

Please note that I changed filter to forEach.

1 Comment

.push of undefined
0

        const products = [
            {
                "id": 1,
                "product_title": "Product 1",
                "product_size": null,
                "product_author": 5,
                "description": "Test Description",
                "product_category": "Shirts,Pents,Salwar",
                "createdAt": "2020-02-08T11:42:15.000Z",
                "updatedAt": "2020-02-08T11:42:15.000Z"
            },
            {
                "id": 4,
                "product_title": "Product 2",
                "product_size": null,
                "product_author": 5,
                "description": "Test Description",
                "product_category": "Pents,Salwar",
                "createdAt": "2020-02-08T11:42:15.000Z",
                "updatedAt": "2020-02-10T07:08:23.000Z"
            }
        ];
        
        const categories = [
            {
                "id": 1,
                "category_name": "Shirts",
                "createdAt": "2020-02-08T04:59:59.000Z",
                "updatedAt": "2020-02-10T06:50:05.000Z"
            },
            {
                "id": 9,
                "category_name": "Pents",
                "createdAt": "2020-02-08T04:59:59.000Z",
                "updatedAt": "2020-02-10T06:50:05.000Z"
            }
        ];
        
     



         const matchedProducts = [];
            products.map(prod=>{
              const isCateoryMatched = categories.some(c=>{
                  return   prod.product_category.includes(c.category_name)
              });
              if(isCateoryMatched ){
                 matchedProducts.push(prod);
              }
            })
        //if you want to push the matched products into categories
            categories.push(...matchedProducts)
    
    console.log('matchedProducts',matchedProducts);
    console.log('categories',categories);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.