2

I have an array of data that is being used for some visualisation and is in the below format

var Dataset1 =  [
      {
        "commentBy" : "saurabh",
        "comment" : "Testing",
        "datestamp" : "07/07/2017",
        "weekcount" : 1
      },
      
       {
        "commentBy" : "raman",
        "comment" : "Planning",
        "datestamp" : "07/07/2017",
        "weekcount" : 1
      },
       {
        "commentBy" : "Execution",
        "comment" : "Alfa Beta",
        "datestamp" : "07/07/2017",
        "weekcount" : 2
      },
        {
        "commentBy" : "Execution",
        "comment" : "Zseta Gama",
        "datestamp" : "07/07/2017",
        "weekcount" : 2
      } 
        ]

//although i have tried writing this function but this is not giving me the desired result.


var groupBy = function(xs, key) {
  return xs.reduce(function(rv, x) {
 
    (rv[x[key]] = rv[x[key]] || []).push(x);
    return rv;
  }, {});
};
var groubedByTeam=groupBy(Dataset1, 'weekcount')
console.log(groubedByTeam);

I want to grouped the dataset by the weekcount so that the desired result should be like this.

    [
    { "weekcount" : 1
       "grouped" : [
          {   "commentBy" : "saurabh",
              "comment" : "Testing",
              "datestamp" : "07/07/2017"
          }, 
          {
               "commentBy" : "raman",
               "comment" : "Planning",
              "datestamp" : "07/07/2017"
           }
      ]    
    }, {
      "weekcount" : 2
          "grouped" : [
           {
        "commentBy" : "Execution",
        "comment" : "Alfa Beta",
        "datestamp" : "07/07/2017",

      },
        {
        "commentBy" : "Execution",
        "comment" : "Zseta Gama",
        "datestamp" : "07/07/2017",

      } 
      ]    
    }
 ]

5 Answers5

2
const formatted = [];

Dataset1.forEach((data) => {
  const { weekcount, comment, commentBy, datestamp } = data;
  let obj = formatted.find((item) => item.weekcount === weekcount);

  if (!obj) {
    formatted.push({
      weekcount,
      grouped: [{
        comment,
        commentBy,
        datestamp
      }]
    })
  } else {
    obj.grouped.push({
      comment,
      commentBy,
      datestamp
    });
  }
});

const Dataset1 = [{
  "commentBy": "saurabh",
  "comment": "Testing",
  "datestamp": "07/07/2017",
  "weekcount": 1
}, {
  "commentBy": "raman",
  "comment": "Planning",
  "datestamp": "07/07/2017",
  "weekcount": 1
}, {
  "commentBy": "Execution",
  "comment": "Alfa Beta",
  "datestamp": "07/07/2017",
  "weekcount": 2
}, {
  "commentBy": "Execution",
  "comment": "Zseta Gama",
  "datestamp": "07/07/2017",
  "weekcount": 2
}];

const formatted = [];

Dataset1.forEach((data) => {
  const { weekcount, comment, commentBy, datestamp } = data;
  let obj = formatted.find((item) => item.weekcount === weekcount);

  if (!obj) {
    formatted.push({
      weekcount,
      grouped: [{
        comment,
        commentBy,
        datestamp
      }]
    })
  } else {
    obj.grouped.push({
      comment,
      commentBy,
      datestamp
    });
  }
});

console.log(formatted);
dork
  • 4,396
  • 2
  • 28
  • 56
  • This is good, but it will force you to rewrite the code each time the format of input changes, for instance when you add some new properties to your data. Check out my solution for that below. – K. Kirsz Jul 10 '17 at 09:01
1

Here is a clean way to group the data, you should be able to figure out how to format it the way you want with this as a starting point.

grouped = {}

Dataset1.forEach(function(item, index){

    if (!grouped[item.weekcount]) grouped[item.weekcount] = [];
    grouped[item.weekcount].push(item);

});

grouped is an object keyed with the weekcount. If a certain weekcount doesn't exist as a key in the object, an empty array is created and then the data is pushed to it. On later iterations data with the same weekcount is added to the existing array.

Christopher Reid
  • 4,318
  • 3
  • 35
  • 74
  • Wouldn't the output of that be `{ 0: [{ comment: 'Testing', commentBy: 'saurabh', datestamp: '07/07/2017', weekcount: 1 }, { ... }], 1: [{ ... }, { ... }] }`? The desired result is `[{ weekcount: 1, grouped: [{ ... }, { ... }] }, { weekcount: 2, grouped: [{ ... }, { ... }] }]`. https://stackoverflow.com/a/45006708/769326 – dork Jul 10 '17 at 08:43
  • The first sentence of my answer states: "Here is a clean way to group the data, you should be able to figure out how to format it the way you want with this as a starting point" – Christopher Reid Jul 10 '17 at 08:51
1

You could check each weekcount from 0 to max, and filter your array. It could be something like this:

var Dataset1 =  [
      {
        "commentBy" : "saurabh",
        "comment" : "Testing",
        "datestamp" : "07/07/2017",
        "weekcount" : 1
      },

       {
        "commentBy" : "raman",
        "comment" : "Planning",
        "datestamp" : "07/07/2017",
        "weekcount" : 1
      },
       {
        "commentBy" : "Execution",
        "comment" : "Alfa Beta",
        "datestamp" : "07/07/2017",
        "weekcount" : 2
      },
        {
        "commentBy" : "Execution",
        "comment" : "Zseta Gama",
        "datestamp" : "07/07/2017",
        "weekcount" : 2
      } 
        ]

var maxWeekCount = 3;
var result = []
for(var i=0; i<maxWeekCount; i++){
  var group = Dataset1.filter(obj => obj.weekcount === i)
  if(group.length) {
    result.push({
      weekCount: i,
      grouped: group
    })
  }
}

console.log(result)
dloeda
  • 1,516
  • 15
  • 23
1

Use a helper object, that maintains a reference to the weekcount objects, to reduce the array to the grouped structure.

var Dataset1 = [{"commentBy":"saurabh","comment":"Testing","datestamp":"07/07/2017","weekcount":1},{"commentBy":"raman","comment":"Planning","datestamp":"07/07/2017","weekcount":1},{"commentBy":"Execution","comment":"Alfa Beta","datestamp":"07/07/2017","weekcount":2},{"commentBy":"Execution","comment":"Zseta Gama","datestamp":"07/07/2017","weekcount":2}];

var helperMap = {};

var result = Dataset1.reduce(function(arr, obj) {
  var current = helperMap[obj.weekcount];
  
  if(!current) {
    current = { 
      weekcount: obj.weekcount,
      grouped: [] 
    };
    
   helperMap[obj.weekcount] = current;
    
    arr.push(current);
  }

  current.grouped.push({
    commentBy: obj.commentBy,
    comment: obj.comment,
    datestamp: obj.datestamp
  });
  
  return arr;
}, []);

console.log(result);
Ori Drori
  • 183,571
  • 29
  • 224
  • 209
1
var groupBy = function(xs, key) {
  return xs.reduce(function(rv, x) {
    if(rv[x[key]] == undefined){
      rv[x[key]] = {"weekcount": x[key], "grouped": []}
    }
    stripped = {}
    for(var k in x) if(k!=key) stripped[k]=x[k]; //strip "key" property
    rv[x[key]]["grouped"].push(stripped);
    return rv;
  }, []);
};

By stripping the "key" property, this solution works with any input without modification, so if you add/remove some properties from the input, it will still work as expected, reflecting the changes.

K. Kirsz
  • 1,384
  • 10
  • 11