0

I have a json object as below in my web application. It's an array of product objects and each product object has a category property which contains an array of categories that the product belongs to.

var products = [  
   {  
      "id":1,
      "name":"Product 1",
      "price":10,
      "category":[  
         {  
            "id":10,
            "name":"Category 1"
         },
         {  
            "id":20,
            "name":"Category 2"
         }
      ]
   },
   {  
      "id":2,
      "name":"Product 2",
      "price":20,
      "category":[  
         {  
            "id":20,
            "name":"Category 2"
         },
         {  
            "id":30,
            "name":"Category 3"
         }
      ]
   }
]

So now I want to display them grouped by categories so the end result will look like below. I am already using Underscore.js in my project so it will be good if I can use it to achieve this.

var categories = [  
   {  
      "id":10,
      "name":"Category 1",
      "products":[  
         {  
            "id":1,
            "name":"Product 1",
            "price":10
         }
      ]
   },
   {  
      "id":20,
      "name":"Category 2",
      "products":[  
         {  
            "id":1,
            "name":"Product 1",
            "price":10
         }, 
         {
            "id":2,
            "name":"Product 2",
            "price":20,
         }
      ]
   },
   {  
      "id":30,
      "name":"Category 3",
      "products":[  
         {  
            "id":2,
            "name":"Product 2",
            "price":20,
         }
      ]
   }
]

2 Answers 2

3

I'm not entirely sure whether there is an out-of-the-box solution to this problem with underscore, however solving this by hand shouldn't be too hard, either:

var categoriesIndexed = {};
var categories = [];

products.forEach(function(product) {
    product.category.forEach(function(category) {
        // create a new category if it does not exist yet
        if(!categoriesIndexed[category.id]) {
            categoriesIndexed[category.id] = {
                id: category.id,
                name: category.name,
                products: []
            };
            categories.push(categoriesIndexed[category.id]);
        }

        // add the product to the category
        categoriesIndexed[category.id].products.push({
            id: product.id,
            name: product.name,
            price: product.price   
        });
    });
});
Sign up to request clarification or add additional context in comments.

Comments

2

here is what I would do

var categories = [];
var cat = new Map();

var addUniqueCategory(category) { /* determine if category is already in list of categories, if not add it to categories */ };

products.each (function (item) {
     item.categories.each(function (c) {
         if (!cat.has(c.name)) cat.set(c.name, []);

         var list = cat.get(c.name);
         list.push( { id: item.id, name: item.name, price: item.price });

         addUniqueCategory(c);
     });
});

categories.each( function (c) {
    var list = cat.get(c.name);
    if (!c.products) c.products = [];
    c.products.splice( c.length, 0, list);
 });

roughly, I'm on a phone

Comments

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.