Home > Blockchain >  JavaScript group and transform array of objects by one or two keys
JavaScript group and transform array of objects by one or two keys

Time:12-30

How can I group by Date and transform the following data

// PROVIDED INPUT
[
  {
    "Date": "2021/Dec/01",
    "Media category": "Canvas",
    "Printed square meters": 244.58
  },
  {
    "Date": "2021/Dec/01",
    "Media category": "Film",
    "Printed square meters": 152.62
  },
  {
    "Date": "2021/Dec/01",
    "Media category": "Heavy paper > 200gsm",
    "Printed square meters": 256.02000000000004
  },
  {
    "Date": "2021/Dec/02",
    "Media category": "Textile",
    "Printed square meters": 144.95999999999998
  },
  {
    "Date": "2021/Dec/02",
    "Media category": "Thick film > 200 um",
    "Printed square meters": 153.37
  },
  {
    "Date": "2021/Dec/02",
    "Media category": "Paper",
    "Printed square meters": 217.2
  }, ...
]

into this with JavaScript. I tried to accomplish this with Lodash's groupBy() and mergeWith(), but I am not getting anywhere:

// DESIRED OUTPUT
[
  {
    "Date": "2021/Dec/01",
    "Canvas": 244.58,
    "Film": 152.62
    "Heavy paper > 200gsm": 256.02000000000004
  },
  {
    "Date": "2021/Dec/02",
    "Textile": 144.95999999999998,
    "Thick film > 200 um": 153.37
    "Paper": 217.2
  }, ...
]

Also, is it possible to group by two keys - i.e Date and Printer id:

// PROVIDED INPUT
[
  {
    "Date": "2021/Dec/01",
    "Printer id": "700",
    "Media category": "Canvas",
    "Printed square meters": 244.58
  },
  {
    "Date": "2021/Dec/01",
    "Printer id": "700",
    "Media category": "Film",
    "Printed square meters": 152.62
  },
  {
    "Date": "2021/Dec/01",
    "Printer id": "701",
    "Media category": "Heavy paper > 200gsm",
    "Printed square meters": 256.02000000000004
  },
  {
    "Date": "2021/Dec/01",
    "Printer id": "701",
    "Media category": "Textile",
    "Printed square meters": 144.95999999999998
  }, ...
]
// DESIRED OUTPUT
[
  {
    "Date": "2021/Dec/01",
    "Printer id": "700",
    "Canvas": 244.58,
    "Film": 152.62
  },
  {
    "Date": "2021/Dec/01",
    "Printer id": "701",
    "Heavy paper > 200gsm": 256.02000000000004,
    "Textile": 144.95999999999998
  }, ...

I tried doing the first one with this code, but got no idea how to transform the fields:

// What I tried doing
console.log(_(data)
    .groupBy('Date')
    .map(g => _.mergeWith({}, ...g, (obj, src) =>
      _.isArray(obj) ? obj.concat(src) : undefined))
    .value());

Checked many questions before submitting this one but none has the the transformation of fields.

CodePudding user response:

You can create a computed key on Date and Printer id and group based on this key.

const data = [ { "Date": "2021/Dec/01", "Printer id": "700", "Media category": "Canvas", "Printed square meters": 244.58 }, { "Date": "2021/Dec/01", "Printer id": "700", "Media category": "Film", "Printed square meters": 152.62 }, { "Date": "2021/Dec/01", "Printer id": "701", "Media category": "Heavy paper > 200gsm", "Printed square meters": 256.02000000000004 }, { "Date": "2021/Dec/01", "Printer id": "701", "Media category": "Textile", "Printed square meters": 144.95999999999998 }],
      result = Object.values(data.reduce((r, o) => {
        let key = o.Date   '-'   o['Printer id'];
        r[key] ??= {Date: o.Date, 'Printer id': o['Printer id']};
        r[key][o['Media category']] = (r[key][o['Media category']] ?? 0)   o['Printed square meters'];
        return r;
      },{}));
console.log(result);

  • Related