DavidB
DavidB

Reputation: 2596

Count length of items in nested js object

Given an array like this, how would I get a count of all charts in a particular category. Each category can have multiple or no groups.

{
   "categories":[
      {
         "title":"category 1",
         "id":"cat1",
         "groups":[
            {
               "title":"group 1",
               "id":"grp1",
               "charts":[
                  {
                     "title":"chart 1",
                     "id":"chart1",
                     "type":"line"
                  }
               ]
            }
         ]
      },
      {
         "title":"category 2",
         "id":"cat2",
         "charts":[
            {
               "title":"chart 2",
               "id":"chart2",
               "type":"line"
            }
         ]
      },
      {
         "title":"category 3",
         "id":"cat3",
         "charts":[
            {
               "title":"chart 3",
               "id":"chart3",
               "type":"line"
            }
         ]
      }
   ]
}

Upvotes: 0

Views: 482

Answers (4)

Gaurav joshi
Gaurav joshi

Reputation: 1799

Hope this will help you :)

var categories = [
      {
         "title":"category 1",
         "id":"cat1",
         "groups":[
            {
               "title":"group 1",
               "id":"grp1",
               "charts":[
                  {
                     "title":"chart 1",
                     "id":"chart1",
                     "type":"line"
                  }
               ]
            }
         ]
      },
      {
         "title":"category 2",
         "id":"cat2",
         "charts":[
            {
               "title":"chart 2",
               "id":"chart2",
               "type":"line"
            }
         ]
      },
      {
         "title":"category 3",
         "id":"cat3",
         "charts":[
            {
               "title":"chart 3",
               "id":"chart3",
               "type":"line"
            },
           {
               "title":"chart 3",
               "id":"chart3",
               "type":"line"
            },
           {
               "title":"chart 3",
               "id":"chart3",
               "type":"line"
            }
         ]
      },
    {
         "title":"category 4",
         "id":"cat4",
         "groups":[
            {
               "title":"group 4",
               "id":"grp4",
               "charts":[
                  {
                     "title":"chart 1",
                     "id":"chart1",
                     "type":"line"
                  },
                  {
                     "title":"chart 1",
                     "id":"chart1",
                     "type":"line"
                  }
               ]
            }
         ]
      }
   ];


function countCategoryItems(data, category) {
   if(!data ) return 0
   if(!category) return 0

   var cat = _.filter(data, function(obj){ return obj.title == category; });
   if(!cat.length) return 0

   var groups = cat[0].groups || []
   if(!groups.length) return cat[0].charts.length
   
   var count = 0
   for (var i=0;i<groups.length;i++) {
        count += groups[i].charts.length
   }
  
   return count
}

$(function() {
console.log(countCategoryItems(categories, 'category 1'))
console.log(countCategoryItems(categories, 'category 2'))
console.log(countCategoryItems(categories, 'category 3'))
console.log(countCategoryItems(categories, 'category 4'))
})
<script src="http://underscorejs.org/underscore.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Upvotes: 0

Nina Scholz
Nina Scholz

Reputation: 386883

You could count the properties with default.

var data = { "categories": [{ "title": "category 1", "id": "cat1", "groups": [{ "title": "group 1", "id": "grp1", "charts": [{ "title": "chart 1", "id": "chart1", "type": "line" }] }] }, { "title": "category 2", "id": "cat2", "charts": [{ "title": "chart 2", "id": "chart2", "type": "line" }] }, { "title": "category 3", "id": "cat3", "charts": [{ "title": "chart 3", "id": "chart3", "type": "line" }] }] },
    count = {};

data.categories.forEach(function (a) {
    var countCharts = function (r, a) {
        return r + (a.charts || []).length;
    };
    count[a.title] = (count[a.title] || 0) + 
        (a.groups ||[]).reduce(countCharts, 0) +
        countCharts(0, a);
});

console.log(count);

Upvotes: 0

GiuServ
GiuServ

Reputation: 1235

var object = {
  "categories": [{
    "title": "category 1",
    "id": "cat1",
    "groups": [{
      "title": "group 1",
      "id": "grp1",
      "charts": [{
        "title": "chart 1",
        "id": "chart1",
        "type": "line"
      }]
    }]
  }, {
    "title": "category 2",
    "id": "cat2",
    "charts": [{
      "title": "chart 2",
      "id": "chart2",
      "type": "line"
    }]
  }, {
    "title": "category 3",
    "id": "cat3",
    "charts": [{
      "title": "chart 3",
      "id": "chart3",
      "type": "line"
    }]
  }]
}
var groupPerCategories = [];

object.categories.forEach(function(category) {
  var tot = 0;
  if (category.groups != undefined) {
    category.groups.forEach(function(group) {
      if(group.charts != undefined){
          tot += group.charts.length;
      }
    });
  }
  if (category.charts != undefined) {
    tot += category.charts.length;
  }
  console.log(tot);
});

Upvotes: 1

fafl
fafl

Reputation: 7387

Is a one-liner okay?

Assuming data is your JSON structure:

data.categories
    .map(c => [
        c.title,
        c.groups ?
            c.groups.map(g => g.charts.length).reduce((a, b) => a+b) :
            c.charts.length
    ])

Upvotes: 1

Related Questions