Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

underscore js pluck nested key value

I have a JS object like this one

var obj = {
    "2014" : {
        "11" : {
            "20" : {
                "Counts" : {
                    "c" : 2
                }
            },
            "21" : {
                "Counts" : {
                    "c" : 20
                }
            },
            "22" : {
                "Counts" : {
                    "c" : 20
                }
            }
        }
    },
    "_id" : "53d6883a2dc307560d000004",
    "createdate" :"2014-11-21T07:15:26.109Z"
};

As you can see this is structure which contains year>->month->day->counts->c->value structure I want to pluck out the day and Count(c) values out of it

I tried something like this

_.pluck(obj,'11')

but this is good uptil only month, and doesn't work for days like

_pluck(_.pluck(obj,'11'),'20') 
like image 546
Brij Raj Singh - MSFT Avatar asked Nov 21 '14 09:11

Brij Raj Singh - MSFT


2 Answers

You can use map like this. Pluck is a refined version of map.

_.map(obj.2014.11, function (item) {
  return item.Counts.c
}

This will give you an array with all c values embedded in 11. But I would not be suprised if I have misunderstood your intent...

like image 184
Anders Östman Avatar answered Oct 13 '22 22:10

Anders Östman


Personally, I would have created the data structure keyed by date, and then created views (this looks a lot like a couch structure) based on them:

var obj = {
"2014-11-20" : {
   "Counts" : {
      "c" : 2
   }
},
"2014-11-21" : {
   "Counts" : {
      "c" : 20
   }
},
"2014-11-22" : {
   "Counts" : {
      "c" : 20
   }
},
"_id" : "53d6883a2dc307560d000004",
"createdate" :"2014-11-21T07:15:26.109Z"
};

But given your existing structure, you may just need to do a reduce (actually multiple):

var allcounts = _.reduce(obj,function(result,item,key) {
  // key is now "2014", item is the value of {"11":....}
  _.reduce(item,function(result,item,key) {
    // key is now "11", item is the value of {"20":....}
    _.reduce(item,function(result,item,key) {
      // key is now the date, like "20", item is the value of {"Counts":{"c":2}}
      result.push(item.Counts.c);
    },result);
  },result);
},[]);

Ugly, but I cannot think of a better way with this kind of deeply nested data structure

You can limit the range by working with the key var in the first, second, third _.reduce().

like image 21
deitch Avatar answered Oct 14 '22 00:10

deitch