DavidB DavidB - 28 days ago 4
Javascript Question

underscore get nested item by id

I have the following data structure, that contains categories as the top level followed by optional groups and then chart objects which will represent graph data.

Using underscore, or vanilla js I would like to get a particular chart object by its id. I have tried using combinations of _.flatten and _.find but am getting no where.

If its possible to also get a count of charts in a category, based on a charts id that would be awesome.

{
"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"
}
]
}
]
}

Answer

You could use recursive function that will do deep search and return desired result.

var obj = {"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"}]}]}

function findObj(data, id) {
  var result = [];

  if (Array.isArray(data)) {
    data.forEach(function(e) {
      result = result.concat(findObj(e, id))
    })
  } else if (typeof data == 'object' && !Array.isArray(data)) {
    var f = null;
    Object.keys(data).forEach(function(e) {
      if (e == 'id' && data[e] == id) f = data;
    })

    if (f != null) {
      result.push(f);
    } else {
      Object.keys(data).forEach(function(key) {
        if (typeof data[key] == 'object') {
          result = result.concat(findObj(data[key], id));
        }
      })
    }
  }
  return result;
}


console.log(findObj(obj, 'grp1'))
console.log(findObj(obj, 'chart1'))
console.log(findObj(obj, 'cat1'))