1

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.

4
  • Array1 is an Object, not an array Commented Dec 14, 2016 at 13:58
  • I apologize for my mistake. I try to copy it from my console. Commented Dec 14, 2016 at 14:02
  • return returns to the jquery routine... and looping trough all elements in a function that loops trough all elements (some) doesnt make that much sense Commented Dec 14, 2016 at 14:03
  • I know second part of my coding is not good code. Even I put my obj object to newData array is also without sense. Is part of code that I try to get my output. Commented Dec 14, 2016 at 14:10

2 Answers 2

1

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; }

Sign up to request clarification or add additional context in comments.

7 Comments

Thanks @Scholz for response.And I get my output as mentions in question But my problem is I need to loop through 24 hours.What if some hours are not in my response array?
is it always 24 hours? is it starting with zero?
ya, I need to do for 24 hours and some hours cannot be in my Array1 also.
@Scholz just a small question. In your Array.apply how you did i++? I ask you because I need to do same with day interval also.Which part of code is doing increment?This is just my question.
it is the i in the callback function (_, i) { /* ... */}. the API of Array#forEach does incrementing.
|
0

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);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.