Skip to main content

What I'm wondering is, if that method can be simplified with a more modern approach or better written. Like using a different method instead of a reduce.

The snippet of the method will be included at the end of the postreduce.

The method takes the dbData which includes data in the following form:

The data contains two same fields/values as studyId and siteId and what I aggregate is the status, cuurentcurrent, total tobeto be included under the same Study and Site.

The output of the above passing via the method:

So it is reduced to a different form where we have one object per studyId and siteId which includes the currents and totals of the status.

What I'm wondering is, if that method can be simplified with a more modern approach or better written. Like using a different method instead of a reduce.

The snippet of the method will be included at the end of the post.

The method takes the dbData which includes data in the following form

The data contains two same fields/values as studyId and siteId and what I aggregate is the status, cuurent, total tobe included under the same Study and Site.

The output of the above passing via the method

So it is reduced to a different form where we have one object per studyId and siteId which includes the currents and totals of the status

What I'm wondering is, if that method can be simplified with a more modern approach or better written. Like using a different method instead of a reduce.

The method takes the dbData which includes data in the following form:

The data contains two same fields/values as studyId and siteId and what I aggregate is the status, current, total to be included under the same Study and Site.

The output of the above passing via the method:

So it is reduced to a different form where we have one object per studyId and siteId which includes the currents and totals of the status.

edited title
Link
200_success
  • 144.1k
  • 22
  • 188
  • 473

A reduce method which shape incoming data to anew simplified form aggregatedaggregates common data in single objects

Source Link
Jakub
  • 271
  • 2
  • 9

A reduce method which shape incoming data to anew simplified form aggregated common data in single objects

I built a method using reduce of JS to aggregate together data from a DB in a better shape.

What I'm wondering is, if that method can be simplified with a more modern approach or better written. Like using a different method instead of a reduce.

The snippet of the method will be included at the end of the post.

The method takes the dbData which includes data in the following form

const dbData = [{
    studyId: 'X',
    siteId: 'A',
    day: '2000-01-01',
    status: 'PENDING_CALLCENTER',
    current: 5,
    total: 17,
  },
  {
    studyId: 'X',
    siteId: 'A',
    day: '2000-01-01',
    status: 'PENDING_SITE',
    current: 3,
    total: 9,
  },
  {
    studyId: 'Y',
    siteId: 'B',
    day: '2000-01-01',
    status: 'PENDING_SITE',
    current: 3,
    total: 9,
  },
  {
    studyId: 'Y',
    siteId: 'B',
    day: '2000-01-01',
    status: 'PENDING_CALLCENTER',
    current: 3,
    total: 9,
  },
]

The data contains two same fields/values as studyId and siteId and what I aggregate is the status, cuurent, total tobe included under the same Study and Site.

The output of the above passing via the method

[
  {
    "studyId": "X",
    "siteId": "A",
    "currents": {
      "PENDING_CALLCENTER": 5,
      "PENDING_SITE": 3
    },
    "totals": {
      "PENDING_CALLCENTER": 17,
      "PENDING_SITE": 9
    }
  },
  {
    "studyId": "Y",
    "siteId": "B",
    "currents": {
      "PENDING_SITE": 6,
      "PENDING_CALLCENTER": 3
    },
    "totals": {
      "PENDING_SITE": 18,
      "PENDING_CALLCENTER": 9
    }
  }
] 

So it is reduced to a different form where we have one object per studyId and siteId which includes the currents and totals of the status

The method

dbData.reduce((acc, row) => {
const {
  studyId,
  siteId,
  status,
  current,
  total
} = row;
const idx = acc.findIndex(x => studyId === x.studyId && siteId === x.siteId);
const item = idx === -1 ? {
  studyId,
  siteId,
  currents: {},
  totals: {}
} : { ...acc[idx]
};
item.currents[status] = item.currents[status] ? item.currents[status] + current : current;
item.totals[status] = item.totals[status] ? item.totals[status] + total : total;
if (idx === -1) {
  acc.push(item);
} else {
  acc[idx] = item;
}
return acc;
}, []);

A working example

const dbData = [{
    studyId: 'X',
    siteId: 'A',
    day: '2000-01-01',
    status: 'PENDING_CALLCENTER',
    current: 5,
    total: 17,
  },
  {
    studyId: 'X',
    siteId: 'A',
    day: '2000-01-01',
    status: 'PENDING_SITE',
    current: 3,
    total: 9,
  },
  {
    studyId: 'Y',
    siteId: 'B',
    day: '2000-01-01',
    status: 'PENDING_SITE',
    current: 3,
    total: 9,
  },
  {
    studyId: 'Y',
    siteId: 'B',
    day: '2000-01-01',
    status: 'PENDING_CALLCENTER',
    current: 3,
    total: 9,
  },
];


const reduced = dbData.reduce((acc, row) => {
  const {
    studyId,
    siteId,
    status,
    current,
    total
  } = row;
  const idx = acc.findIndex(x => studyId === x.studyId && siteId === x.siteId);
  const item = idx === -1 ? {
    studyId,
    siteId,
    currents: {},
    totals: {}
  } : { ...acc[idx]
  };
  item.currents[status] = item.currents[status] ? item.currents[status] + current : current;
  item.totals[status] = item.totals[status] ? item.totals[status] + total : total;
  if (idx === -1) {
    acc.push(item);
  } else {
    acc[idx] = item;
  }
  return acc;
}, []);

console.log(reduced);