0

I have a function which is returning a js object in this format

{ _id: { day: 21, month: 10, year: 2020 },
  TOTAL: 9,
  A: 4,
  B: 1,
  C: 1,
  D: 2 }

and I have to format the above one into this format:

{ modalities:
   { TOTAL: { '21-09-2020': 2, '20-10-2020': 1, '21-10-2020': 8 },
     A: { '21-09-2020': 1, '21-10-2020': 4 },
     B: { '21-10-2020': 1 },
     C: { '21-09-2020': 1, '21-10-2020': 1 },
     D: { '20-10-2020': 1, '21-10-2020': 2 } } }

as a beginner, I don't have much experience with formatting and right now I'm thinking to implement this with forEach. Is there any better way to do it in javascript?

2
  • This is a bit of a tricky "groupBy" operation. Are you certain you want the dates as keys in final output? It doesn't make it any more difficult to create but standardized key names are easier to work with once you have it transformed Commented Oct 26, 2020 at 6:13
  • Yes, I want this to be specified in that format and I'm not entirely sure how to do it. Commented Oct 26, 2020 at 6:19

2 Answers 2

1

You can use .reduce as below, by iterating over objects and merging them into single object.

Below code will add any dynamic keys as well, except _id, (if you want you can hardcode keys if you want strict schema).

const temp = [{"_id":{"day":21,"month":10,"year":2020},"TOTAL":9,"XR":4,"CT":1,"MR":1,"MG":2},{"_id":{"day":20,"month":10,"year":2020},"TOTAL":1,"XR":0,"CT":0,"MR":0,"MG":1},{"_id":{"day":21,"month":9,"year":2020},"TOTAL":2,"XR":1,"CT":0,"MR":1,"MG":0}];

const result = temp.reduce((res, obj) => {
  const id = `${obj._id.day}-${obj._id.month}-${obj._id.year}`;
  for (let key in obj) {
    if (key === '_id') // Skip _id, as we don't want in resulting object
      continue;
    if(obj[key]){  // As OP output skips 0 valued keys
      res.modalities[key] = res.modalities[key] || {};
      res.modalities[key][id] = obj[key];
   }
  }
  return res;
}, {modalities:{}});

console.log(result)

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

5 Comments

Oh, so that's how we can use reduce in this condition. Thanks, that's a good one.
Will you please point out some links where I can get more information around the map and reduce things?
One last question, what if we want to sort the dates accordingly?
modalities and all inside values are Objects with key value pairs, javascript keys will not be sorted. You have to either convert them to array then come up with example how do you wanna sort this. Ref: stackoverflow.com/questions/1069666/…
1
let data = [
  {
    "_id": {
      "day": 21,
      "month": 10,
      "year": 2020
    },
    "TOTAL": 9,
    "XR": 4,
    "CT": 1,
    "MR": 1,
    "MG": 2
  },
  {
    "_id": {
      "day": 20,
      "month": 10,
      "year": 2020
    },
    "TOTAL": 1,
    "XR": 0,
    "CT": 0,
    "MR": 0,
    "MG": 1
  },
  {
    "_id": {
      "day": 21,
      "month": 9,
      "year": 2020
    },
    "TOTAL": 2,
    "XR": 1,
    "CT": 0,
    "MR": 1,
    "MG": 0
  }
];

let result = {
    modalities: {
        TOTAL: {},
        XR: {},
        CT: {},
        MR: {},
        MG: {}
    }
};

for (let element of data) {
    let date = element._id.day + '-' + element._id.month + '-' + element._id.year;
    result.modalities.TOTAL[date] = element.TOTAL;
    result.modalities.XR[date] = element.XR;
    result.modalities.CT[date] = element.CT;
    result.modalities.MR[date] = element.MR;
    result.modalities.MG[date] = element.MG;
}

console.log('result: ' + JSON.stringify(result));

sample output

result: {
  "modalities": {
    "TOTAL": {
      "21-10-2020": 9,
      "20-10-2020": 1,
      "21-9-2020": 2
    },
    "XR": {
      "21-10-2020": 4,
      "20-10-2020": 0,
      "21-9-2020": 1
    },
    "CT": {
      "21-10-2020": 1,
      "20-10-2020": 0,
      "21-9-2020": 0
    },
    "MR": {
      "21-10-2020": 1,
      "20-10-2020": 0,
      "21-9-2020": 1
    },
    "MG": {
      "21-10-2020": 2,
      "20-10-2020": 1,
      "21-9-2020": 0
    }
  }
}

2 Comments

It's working, but is there any other workaround other than for and foreach?
i suppose you can use while loop. or did you want to avoid looping? for loops make the most sense in my opinion

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.