skip to Main Content

I need to merge count records based on comparing common sID and nID. Below are the raw data on which I want to merge records.

So, in the below records for sID 2, nID 111 and sID 2, nID 222 there are total four JSON object. In same sID and nID object there is a value of ar and in another object, there is a value of mr. So, I need to merge those records into one JSON object.

Basically, the records are vice versa. In one JSON the records will be for status.count.mr and in another JSON the records will be for status.count.ar. So, that is the reason I need to combine both status.count.mr and status.count.ar into one object for a specific sID of nID

const records = [
{division: {name: "AAA", sId: 1, nId: 111}, status: {dates: {nDate: "02-20", dDate: "03-20"}, count: {emr: 0, mr: 0, ar: 0, totalAR: 0, totalEMR: 10, totalMR: 0}}},
{division: {name: "AAA", sId: 1, nId: 222}, status: {dates: {nDate: "02-19", dDate: "03-20"}, count: {emr: 0, mr: 0, ar: 0, totalAR: 0, totalEMR: 10, totalMR: 0}}}
{division: {name: "BBB", sId: 2, nId: 111}, status: {dates: {nDate: "02-20", dDate: "03-20"}, count: {emr: 0, mr: 5, ar: 0, totalAR: 0, totalEMR: 0, totalMR: 9}}}
{division: {name: "BBB", sId: 2, nId: 111}, status: {dates: {nDate: "02-20", dDate: "03-20"}, count: {emr: 0, mr: 0, ar: 2, totalAR: 7, totalEMR: 0, totalMR: 0}}}
{division: {name: "BBB", sId: 2, nId: 222}, status: {dates: {nDate: "02-19", dDate: "03-20"}, count: {emr: 0, mr: 3, ar: 0, totalAR: 0, totalEMR: 0, totalMR: 9}}}
{division: {name: "BBB", sId: 2, nId: 222}, status: {dates: {nDate: "02-19", dDate: "03-20"}, count: {emr: 0, mr: 0, ar: 4, totalAR: 7, totalEMR: 0, totalMR: 0}}}
]

For that I have tried below solution.

const mergedMap = new Map();
  for (const record of records) {
    const { sId, nId } = record.division;
    const existingRecord = mergedMap.get(`${sId}-${nId}`);

    if (existingRecord) {
      mergedMap.set(`${sId}-${nId}`, {
        division: existingRecord.division,
        status: {...existingRecord.status, 
          count: {...existingRecord.status.count, ...record.status.count}, 
          dates: {...existingRecord.status.dates, ...record.status.dates},
        },
      });
    } else {
      mergedMap.set(`${sId}-${nId}`, record);
    }
  }
const mergedData = Array.from(mergedMap.values());

Result which I need is as below.

const mergedData = [
{division: {name: "AAA", sId: 1, nId: 111}, status: {dates: {...}, count: {emr: 0, mr: 0, ar: 0, totalAR: 0, totalEMR: 10, totalMR: 0}}},
{division: {name: "AAA", sId: 1, nId: 222}, status: {dates: {...}, count: {emr: 0, mr: 0, ar: 0, totalAR: 0, totalEMR: 10, totalMR: 0}}}
{division: {name: "BBB", sId: 2, nId: 111}, status: {dates: {...}, count: {emr: 0, mr: 5, ar: 2, totalAR: 7, totalEMR: 0, totalMR: 9}}}
{division: {name: "BBB", sId: 2, nId: 222}, status: {dates: {...}, count: {emr: 0, mr: 3, ar: 4, totalAR: 7, totalEMR: 0, totalMR: 9}}}
]

P.S: From above code snippet I am getting the result without copying the mr and totalMR values. So the result which I am gettitng is as below

const mergedData = [
{division: {name: "AAA", sId: 1, nId: 111}, status: {dates: {...}, count: {emr: 0, mr: 0, ar: 0, totalAR: 0, totalEMR: 10, totalMR: 0}}},
{division: {name: "AAA", sId: 1, nId: 222}, status: {dates: {...}, count: {emr: 0, mr: 0, ar: 0, totalAR: 0, totalEMR: 10, totalMR: 0}}}
{division: {name: "BBB", sId: 2, nId: 111}, status: {dates: {...}, count: {emr: 0, mr: 0, ar: 2, totalAR: 7, totalEMR: 0, totalMR: 0}}}
{division: {name: "BBB", sId: 2, nId: 222}, status: {dates: {...}, count: {emr: 0, mr: 0, ar: 4, totalAR: 7, totalEMR: 0, totalMR: 0}}}
]

2

Answers


  1. You could group and then add the counts.

    const
        records = [{ division: { name: "AAA", sId: 1, nId: 111 }, status: { dates: { nDate: "02-20", dDate: "03-20" }, count: { emr: 0, mr: 0, ar: 0, totalAR: 0, totalEMR: 10, totalMR: 0 } } }, { division: { name: "AAA", sId: 1, nId: 222 }, status: { dates: { nDate: "02-19", dDate: "03-20" }, count: { emr: 0, mr: 0, ar: 0, totalAR: 0, totalEMR: 10, totalMR: 0 } } }, { division: { name: "BBB", sId: 2, nId: 111 }, status: { dates: { nDate: "02-20", dDate: "03-20" }, count: { emr: 0, mr: 5, ar: 0, totalAR: 0, totalEMR: 0, totalMR: 9 } } }, { division: { name: "BBB", sId: 2, nId: 111 }, status: { dates: { nDate: "02-20", dDate: "03-20" }, count: { emr: 0, mr: 0, ar: 2, totalAR: 7, totalEMR: 0, totalMR: 0 } } }, { division: { name: "BBB", sId: 2, nId: 222 }, status: { dates: { nDate: "02-19", dDate: "03-20" }, count: { emr: 0, mr: 3, ar: 0, totalAR: 0, totalEMR: 0, totalMR: 9 } } }, { division: { name: "BBB", sId: 2, nId: 222 }, status: { dates: { nDate: "02-19", dDate: "03-20" }, count: { emr: 0, mr: 0, ar: 4, totalAR: 7, totalEMR: 0, totalMR: 0 } } }],
        addObject = (a, b) => Object.fromEntries(Object.entries(a).map(([k, v]) => [k, v + b[k]])),
        grouped = Object
            .values(Object.groupBy(records, ({ division: { sId, nId } }) => sId + '|' + nId))
            .map(data => data.reduce((a, b) => ({
                ...a,
                status: {
                   ...a.status, 
                    count: addObject(a.status.count, b.status.count)
                }
            })));
    
    console.log(grouped);
    .as-console-wrapper { max-height: 100% !important; top: 0; }
    Login or Signup to reply.
  2. It seems like the issue you’re encountering is due to the way JavaScript handles object merging with the spread operator. When you merge two objects that have the same keys, the values from the second object will overwrite the values from the first object for those keys. This is why you’re not seeing the mr and totalMR values being preserved as you expect.

    To solve this, you need to explicitly handle the merging of the count object to ensure that values from both records are summed up rather than overwritten. Here’s an updated version of your loop that does this:

    function mergeRecords(records) {
      const mergedMap = new Map();
      for (const record of records) {
        const { sId, nId } = record.division;
        const key = `${sId}-${nId}`;
        const existingRecord = mergedMap.get(key);
    
        if (existingRecord) {
          // Explicitly sum up the count values
          const updatedCount = Object.keys(existingRecord.status.count).reduce((acc, key) => {
            acc[key] = (existingRecord.status.count[key] || 0) + (record.status.count[key] || 0);
            return acc;
          }, {});
    
          mergedMap.set(key, {
            division: existingRecord.division,
            status: {
              dates: { ...existingRecord.status.dates, ...record.status.dates },
              count: updatedCount,
            },
          });
        } else {
          mergedMap.set(key, record);
        }
      }
      return Array.from(mergedMap.values());
    }
    
    const records = [
      {division: {name: "AAA", sId: 1, nId: 111}, status: {dates: {nDate: "02-20", dDate: "03-20"}, count: {emr: 0, mr: 0, ar: 0, totalAR: 0, totalEMR: 10, totalMR: 0}}},
      {division: {name: "AAA", sId: 1, nId: 222}, status: {dates: {nDate: "02-19", dDate: "03-20"}, count: {emr: 0, mr: 0, ar: 0, totalAR: 0, totalEMR: 10, totalMR: 0}}},
      {division: {name: "BBB", sId: 2, nId: 111}, status: {dates: {nDate: "02-20", dDate: "03-20"}, count: {emr: 0, mr: 5, ar: 0, totalAR: 0, totalEMR: 0, totalMR: 9}}},
      {division: {name: "BBB", sId: 2, nId: 111}, status: {dates: {nDate: "02-20", dDate: "03-20"}, count: {emr: 0, mr: 0, ar: 2, totalAR: 7, totalEMR: 0, totalMR: 0}}},
      {division: {name: "BBB", sId: 2, nId: 222}, status: {dates: {nDate: "02-19", dDate: "03-20"}, count: {emr: 0, mr: 3, ar: 0, totalAR: 0, totalEMR: 0, totalMR: 9}}},
      {division: {name: "BBB", sId: 2, nId: 222}, status: {dates: {nDate: "02-19", dDate: "03-20"}, count: {emr: 0, mr: 0, ar: 4, totalAR: 7, totalEMR: 0, totalMR: 0}}}
    ];
    
    const mergedData = mergeRecords(records);
    console.log(mergedData);

    This code snippet explicitly handles the merging of the count object by iterating over its keys and summing the values from both the existing record and the current record being processed. This ensures that all values, including mr and totalMR, are correctly merged and summed up, producing the desired output.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search