Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

204
Views
How to reduce some data into a new array of objects?

update I tried my own solution and this is what I did maybe can be done better

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_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);

I'm new to using reduce and I have some difficulties understanding how to use it correctly.

I would like to solve a problem where I need to reduce some data in a new array of obj with a different shape.

I have some data

[
      {
        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,
      },
    ];

I want to reduce this to this new data

[
      {
        studyId: 'X',
        siteId: 'A',
        currents: {
          PENDING_CALLCENTER: 5,
          PENDING_SITE: 3,
        },
        totals: {
          PENDING_CALLCENTER: 17,
          PENDING_SITE: 9,
        },
      },
    ];

To learn I was able to create a reducer which calc sum and that I did it but the above problem I have just difficulties to start and want to understand it.

about 4 years ago · Juan Pablo Isaza
2 answers
Answer question

0

You can try something like this :

Please note - I haven't considered validation/exception handling. This is just one way of using a reduce for your data. You could also find a cute way of reducing lines of code - feel free :-)

const arr = [
  {
    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,
  },
];

const res = arr.reduce((accum, curr) => {
  const exist = accum.find(e => e.studyId === curr.studyId && e.siteId === curr.siteId);
  if (exist) {
    exist.currents[curr.status] += curr.current;
    exist.totals[curr.status] += curr.total;
  } else {
    const elem = {
      studyId: curr.studyId,
      siteId: curr.siteId,
      currents: {
        PENDING_CALLCENTER: 0,
        PENDING_SITE: 0,
      },
      totals: {
        PENDING_CALLCENTER: 0,
        PENDING_SITE: 0,
      }
    }
    elem.currents[curr.status] = curr.current;
    elem.totals[curr.status] = curr.total;
    accum.push(elem);
  }
  return accum;
}, []);

console.log(res);

Output:

[
  {
    studyId: 'X',
    siteId: 'A',
    currents: { PENDING_CALLCENTER: 5, PENDING_SITE: 3 },
    totals: { PENDING_CALLCENTER: 17, PENDING_SITE: 9 }
  }
]

about 4 years ago · Juan Pablo Isaza Report

0

The following reducer functionality just merges the currents and totals values of objects of same IDs. Thus, for duplicate items like provided by the OP with a duplicate for Y/B, number values for same properties will be overwritten but not summed-up.

function mergeCurrentsAndTotalsOfSameIds({ lookup = new Map, result }, item) {
  const { studyId, siteId, status, current, total } = item;
  const mergerKey = [studyId, '_###_', siteId].join('');

  let merger = lookup.get(mergerKey);
  if (!merger) {

    merger = { studyId, siteId, currents: {}, totals: {} };

    lookup.set(mergerKey, merger);
    result.push(merger);
  }
  merger.currents[status] = current;
  merger.totals[status] = total;

  return { lookup, result };
}

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_SITE',
  current: 3,
  total: 9,
}, {
  studyId: 'Y',
  siteId: 'B',
  day: '2000-01-01',
  status: 'PENDING_CALLCENTER',
  current: 3,
  total: 9,
}];

const { result: mergedData } = dbData
  .reduce(mergeCurrentsAndTotalsOfSameIds, {result: [] })

console.log({ mergedData, dbData });
.as-console-wrapper { min-height: 100%!important; top: 0; }

about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!