skip to Main Content

I have a list of objects like

const usageCosts = {
    224910186407: {
        deviceId: "224910186407",
        currency: "GBP",
        yearlyUsage: 1480.81
    },
    224910464538: {
        deviceId: "224910464538",
        currency: "GBP",
        yearlyUsage: 617.36
    },
    224910464577: {
        deviceId: "224910464577",
        currency: "EUR",
        yearlyUsage: 522.3
    }
}

I’m reducing it to sum by currency like

 const totalYearlyCost = Object.values(usageCosts).reduce(
      (acc: { [key: string]: any }, stat: any) => {
        if (stat.currency && !acc[stat.currency]) {
          acc[stat.currency] = 0
        }
        return {
          ...acc,
          [stat.currency!]: acc[stat.currency!] + stat.yearlyUsage,
        }
      },
      {},
    )

and it returns an object like

{
EUR: 522.3
GBP: 2,098.17
}

I want to also return the total devices of each currency, something like:

{
EUR: 522.3 (1 device)
GBP: 2,098.17 (2 devices)
}

tried to add another loop but it’s not working as expected

2

Answers


  1. It’s a lot easier to do this in 2 parts.

    First reduce it to an array with the grouped values.

    Then loop over (could also a reduce ofc) the object, and get the sum of the array, and add ${array.length} devices to the string:

    const usageCosts = {
        224910186407: {
            deviceId: "224910186407",
            currency: "GBP",
            yearlyUsage: 1480.81
        },
        224910464538: {
            deviceId: "224910464538",
            currency: "GBP",
            yearlyUsage: 617.36
        },
        224910464577: {
            deviceId: "224910464577",
            currency: "EUR",
            yearlyUsage: 522.3
        }
    }
    
    let grouped = Object.values(usageCosts).reduce((p, c) => {
        if (!p[c.currency]) p[c.currency] = [];
        p[c.currency].push(c.yearlyUsage);
        return p;
    }, {});
    
    for (var key in grouped) {
        grouped[key] = `${grouped[key].reduce((a,b)=>a+b)} (${grouped[key].length}) devices`;
    }
    
    console.log(grouped)
    Login or Signup to reply.
  2. here is a solution:

    const result = Object.values(usageCosts).reduce((acc, stat) => {
        if (stat.currency && !acc[stat.currency]) {
            acc[stat.currency] = {
                total: 0,
                devices: 0,
            }
        }
    
        return {
            ...acc,
            [stat.currency]: {
                total: acc[stat.currency].total + stat.yearlyUsage,
                devices: acc[stat.currency].devices + 1,
            }
        };
    }, {});
    

    As a result, you will get the following structure:

    {
      GBP: { total: 2098.17, devices: 2 },
      EUR: { total: 522.3, devices: 1 }
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search