Dev
Dev

Reputation: 355

Check if key value exist and if not push key with value in javascript

Suppose I have response array from my web-service like this

Array1 = [
      0:[{name:A,count:2,hours:3},{name:B,count:3,hours:3},{name:C,count:2,hours:4}]
      1:[{name:A,count:3,hours:4},{name:B,count:3,hours:3},{name:C,count:2,hours:2}]
      2:[{name:A,count:3,hours:1},{name:B,count:3,hours:4},{name:C,count:2,hours:5},{name:D,count:2,hours:3}]
    ];

and

Array2 = ['A','B','C','D'];

In my output, I need to check for 24 hours.But for simplicity,we will now take only hours to 5.Each sub array from Array1 belong to one user. Now,I must group array by hours and activity. Means I need to make key as name and value as total count of name in each hours.

And output must look like this

var output = [
               {hours:1, A:3, B:0, C:0, D:0},
               {hours:2, A:0, B:0, C:2, D:0},
               {hours:3, A:2, B:6, C:0, D:2},
               {hours:4, A:3, B:3, C:2, D:0},
               {hours:5, A:0, B:0, C:2, D:0},
             ];

And my try below

angular.forEach(Array1 , function(array){ //angularjs foreach
    array.forEach(function(a){
      obj[a.hours] = obj[a.hours]||[0];
      if(obj[a.hours].hasOwnProperty(a.name)){
        obj[a.hours][a.name] = parseInt(obj[a.hours][a.name]) + parseInt(a.count);
      }else{
        obj[a.hours][a.name] = parseInt(a.count);
      }
      obj[a.hours]['hours'] = a.hours;
    });
  });

where I try to group my array with hours and name as key and total count as value. What more I try is

 var startHour = 1;
 var endHours = 5;
 var newData = [];  //@TODO
 newData.push(obj); //@TODO
 for(i= startDate; i < endDate; i++) {
    var found = newData.some(function(el){
      //el.forEach(function(a){
        $.each(el, function(key, value) {
          if(value.hours){
            return value.hours === i;
          }
      });
    });
    if(!found){
      console.log(i + "not found");
      newData.push([{'hours':i}]);
    }
  }
  console.log(newData);

But every time I am in not found.As my output I need to push key-value pairs name and count 0 if not exit. But first I try to push only hours if not exists. Can anyone suggest me what I did wrong. I am back-end programmer so,I don't have good knowledge of JavaScript.

Thank You.

Upvotes: 1

Views: 1022

Answers (2)

Nina Scholz
Nina Scholz

Reputation: 386883

You could use a hash table for the reference of the right hour object and iterate the data with Array#forEach. Later sort the result array for the wanted order.

var array1 = [[{ name: 'A', count: 2, hours: 3 }, { name: 'B', count: 3, hours: 3 }, { name: 'C', count: 2, hours: 4 }], [{ name: 'A', count: 3, hours: 4 }, { name: 'B', count: 3, hours: 3 }, { name: 'C', count: 2, hours: 2 }], [{ name: 'A', count: 3, hours: 1 }, { name: 'B', count: 3, hours: 4 }, { name: 'C', count: 2, hours: 5 }, { name: 'D', count: 2, hours: 3 }]],
    array2 = ['A', 'B', 'C', 'D'],
    grouped = [];

array1.forEach(function (a) {
    a.forEach(function (b) {
        if (!this[b.hours]) {
            this[b.hours] = { hours: b.hours };
            array2.forEach(function (c) { this[c] = 0; }, this[b.hours]);
            grouped.push(this[b.hours]);
        }
        this[b.hours][b.name] += b.count;
    }, this);
}, Object.create(null));

grouped.sort(function (a, b) { return a.hours - b.hours; });

console.log(grouped);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Proposal with 24h array, with zero based hour.

var array1 = [[{ name: 'A', count: 2, hours: 3 }, { name: 'B', count: 3, hours: 3 }, { name: 'C', count: 2, hours: 4 }], [{ name: 'A', count: 3, hours: 4 }, { name: 'B', count: 3, hours: 3 }, { name: 'C', count: 2, hours: 2 }], [{ name: 'A', count: 3, hours: 1 }, { name: 'B', count: 3, hours: 4 }, { name: 'C', count: 2, hours: 5 }, { name: 'D', count: 2, hours: 3 }]],
    array2 = ['A', 'B', 'C', 'D'],
    grouped = Array.apply(null, { length: 24 }).map(function (_, i) {
        var o = { hours: i }
        array2.forEach(function (a) { this[a] = 0; }, o);
        return o;
    });

array1.forEach(function (a) {
    a.forEach(function (b) {
        grouped[b.hours][b.name] += b.count;
    }, this);
}, Object.create(null));

console.log(grouped);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Upvotes: 1

kevin ternet
kevin ternet

Reputation: 4612

You could start on a array of object (1 object per hour). And pushing inside this array the new additional count coresponding the hour and name :

var Array1 = [[{name: "A",count: 2,hours: 3},{name: "B",count: 3,hours: 3},{name: "C",count: 2,hours: 4}],[{name: "A",count: 3,hours: 4},{name: "B",count: 3,hours: 3},{name: "C",count: 2,hours: 2}],[{name: "A",count: 3,hours: 1},{name: "B",count: 3,hours: 4},{name: "C",count: 2,hours: 5},{name: "D",count: 2,hours: 3}]];
var Array2 = ['A','B','C','D'];
var res = [1,2,3,4,5].map(x => ({"hours": x})).map(x => {
  Array2.forEach(y => x[y] = 0);
  return x;
});
Array1.reduce((a,b) => a.concat(b)).forEach(x => {
  if (Array2.indexOf(x.name) !== -1)
    res[x.hours - 1][x.name] += x.count;
})
console.log(res);

Upvotes: 0

Related Questions