0

So I have an existing array with three objects:

              [ { date: 3/12/2022, oService: 10}
                { date: 3/13/2022, oService: 12, aService: 1}
                { date: 3/13/2022, oService: 1 }]

Based on the date, I would like to get something that looks like the following:

                [ {date: 3/12/2022, oService: 10}
                  {date: 3/13/2022, oService: 13, aService: 1}]

additionally, I could have up to 10 services, so I cant reduce by prev.oService. I'll have an array of services that looks something like:

const Services = [aService, bService, cService, oService, yService]

7
  • What about Array.prototype.filter() (developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…)? Commented Mar 15, 2022 at 10:09
  • I tried that, but Im not sure how i would compare the previous dates with filter. Commented Mar 15, 2022 at 10:14
  • I understand that you only want those entries in the array with a specific date? Then filter is the way to go. Commented Mar 15, 2022 at 10:17
  • 1
    Does this answer your question? Most efficient method to groupby on an array of objects Commented Mar 15, 2022 at 10:23
  • 1
    @Dani thats exactly what I have in the clipboard right now :) Commented Mar 15, 2022 at 10:28

1 Answer 1

1

I think it's best to think of the problem as 2 different steps:

  • First, get all things that belong to the same date together. This is a groupBy that you should be able to look up on StackOverflow or borrow from an existing library.
  • Then, you merge each of the date groups in to a single object.

The merge operation is a bit more custom than the groupBy operation. You can implement it in many ways. I would propose to:

  • Implement merge to deal with just 2 objects
  • Inside merge, loop over all unique keys in those objects and sum them (excluding the date key)
  • To apply merge to a date group, use reduce. Note that it's safe to not provide a seed argument here, because you are guaranteed to not have empty groups.

// Merge two date-service entries in to one
const merge = (a, b) => {
  const merged = Object.assign({}, a);
  
  Object.keys(b).forEach(k => {
    if (k !== "date")
      merged[k] = (merged[k] || 0) + b[k];
  });
  
  return merged;
};

const input = [ { date: "3/12/2022", oService: 10},
                { date: "3/13/2022", oService: 12, aService: 1},
                { date: "3/13/2022", oService: 1 }];
          
// Create groups that have a matching date
const byDate = groupByProp("date", input);

// Reduce each group to a single item by merging
const all = Object.values(byDate).map(xs => xs.reduce(merge));

console.log(all);

// A basic `groupBy` implementation
function groupByProp(prop, xs) { 
  return xs.reduce(
    (groups, x) => {
      const k = x[prop];
      if (!groups[k]) groups[k] = [x];
      else groups[k].push(x);
      return groups;
    },
    {}
  );
}

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

1 Comment

Yes, thank you so much. This is the right solution.

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.