1

How can I count the number of non-empty dailyemails in the following json?

{
   "templates":[
      {
         "id":"2c1d99d9b6b2fb417601d24c10c9b041a7d6f37b",
         "dailyemails":[
            "saaa@aa.com",
            "aaa.aaa@gmail.com"
         ],
         "name":"Registration Report"             
      },
      {
         "id":"45s4dsf4qdgze5zef1z3e2f1zevcd5s6sdfsdfsdf",
         "dailyemails":[
         ],
         "name":"Presentation"             
      },
      {
         "id":"7d7cc642ca13cc4a998cad364dfe8e623fd95ae3",
         "dailyemails":[
            "saaa@ss.com"
         ],
         "name":"Live Report"
      }

   ]
}

I am currently reading the total number of nodes Object.keys(myArr).length:

function metaInfo (id, cb){

    var URL = someURLhere
    var count = []

    fs.readFile(__dirname +'/' + URL+'/myFile.json', 'utf8', function   (err, data) {
        if (err) cb (err);
        obj = JSON.parse(data);
        var myArr = obj.nodes;
        count.push(Object.keys(myArr).length);
        cb(null, count)
    });
};

How can I read the number of non-empty dailyemails?

passion
  • 1,000
  • 6
  • 20
  • 47
  • 1
    Probably to loop and count, but if your json is compressed, than you could look for and count `"dailyemails":[]` - it may speed up the process (method [here](http://stackoverflow.com/questions/4009756/how-to-count-string-occurrence-in-string)). – skobaljic Apr 26 '17 at 15:03
  • Use `map` and `filter`, and then count the resulting length. – evolutionxbox Apr 26 '17 at 15:19

4 Answers4

2

filter all empty values out

var count = obj.templates.filter(item => item.dailyemails.length).length
Yury Tarabanko
  • 44,270
  • 9
  • 84
  • 98
2

Instead of creating an array with filter and then getting the length you can also use reduce. This doesn't have the same overhead as filter because the only thing you are storing is the counter in the temporary variable p.

var x = {
   "templates":[
      {
         "id":"2c1d99d9b6b2fb417601d24c10c9b041a7d6f37b",
         "dailyemails":[
            "saaa@aa.com",
            "aaa.aaa@gmail.com"
         ],
         "name":"Registration Report"             
      },
      {
         "id":"45s4dsf4qdgze5zef1z3e2f1zevcd5s6sdfsdfsdf",
         "dailyemails":[
         ],
         "name":"Presentation"             
      },
      {
         "id":"7d7cc642ca13cc4a998cad364dfe8e623fd95ae3",
         "dailyemails":[
            "saaa@ss.com"
         ],
         "name":"Live Report"
      }

   ]
}

alert(x["templates"].reduce(function(p, e)
              {
                if(e["dailyemails"].length !==0)
                    p+=1;
                return p;
              },0));
Luke Kot-Zaniewski
  • 1,161
  • 11
  • 12
2

You can use reduce like this:

var count = myArray.reduce(function(c, o) {
    return c + (o.dailyemails.length? 1: 0);
}, 0);

even shorter using arrow functions:

var count = myArray.reduce((c, o) => c + (o.dailyemails.length? 1: 0), 0);
ibrahim mahrir
  • 31,174
  • 5
  • 48
  • 73
2

You need to make use of the Array filter method.

var obj = {
   "templates":[
      {
         "id":"2c1d99d9b6b2fb417601d24c10c9b041a7d6f37b",
         "dailyemails":[
            "saaa@aa.com",
            "aaa.aaa@gmail.com"
         ],
         "name":"Registration Report"             
      },
      {
         "id":"45s4dsf4qdgze5zef1z3e2f1zevcd5s6sdfsdfsdf",
         "dailyemails":[
         ],
         "name":"Presentation"             
      },
      {
         "id":"7d7cc642ca13cc4a998cad364dfe8e623fd95ae3",
         "dailyemails":[
            "saaa@ss.com"
         ],
         "name":"Live Report"
      }

   ]
};

var nonEmptyDailyEmails = obj.templates.filter(x => x.dailyemails && x.dailyemails.length > 0);
var countOfnonEmptyDailyEmails = nonEmptyDailyEmails.length;
console.log(countOfnonEmptyDailyEmails);
   
Abhinav Galodha
  • 9,293
  • 2
  • 31
  • 41