How Do I do a group by a sum in a list in Tray.io?

52 Views Asked by At

I have a list like this

        {
            "user_email": "[email protected]",
            "duration": 320
        },
        {
            "user_email": "[email protected]",
            "duration": 167,
        },
                {
            "user_email": "[email protected]",
            "duration": 450
        }

and I need to build a new list groupig by user_mail and sum the duration

I need to obtain a list like this

        {
            "user_email": "[email protected]",
            "duration": 167,
        },
                {
            "user_email": "[email protected]",
            "duration": 770
        }
2

There are 2 best solutions below

0
On

I would complete that transformation with a Tray.io script step containing the following code:

exports.step = function(input, fileInput) {
  const data = input.data;
  const result = {};
  
  data.forEach(entry => {
    const userEmail = entry.user_email;
    const duration = entry.duration;
    if (result.hasOwnProperty(userEmail)) {
      result[userEmail] += duration;
    } else {
      result[userEmail] = duration;
    }
  });
  
  const outputData = Object.keys(result).map(userEmail => ({
    user_email: userEmail,
    duration: result[userEmail],
  }));

  return outputData; 
}

The original array of objects is passed as "data" on the input.

Resulting script output

Script step and input

0
On

If you are doing this in a JavaScript/Node environment, you can reduce the objects into a Map and then map the resulting entries back into an array.

Here is a very functional approach to achieve this:

const exports = {};

exports.step = (input, fileInput) =>
  [...input.data
    .reduce((map, { user_email, duration }) =>
      map.set(user_email, (map.get(user_email) ?? 0) + duration), new Map)
    .entries()]
    .map(([user_email, duration]) => ({ user_email, duration }));

const input = {
  data: [
    { "user_email": "[email protected]" , "duration": 320 },
    { "user_email": "[email protected]"   , "duration": 167 },
    { "user_email": "[email protected]" , "duration": 450 }
  ]
};

const output = exports.step(input);

console.log(output);
.as-console-wrapper { top: 0; max-height: 100% !important; }