0

I have an object with an array which contains another array. I need to add up the values from these child arrays where the name matches each other.

let arr = {
    expenses: [
        {
            id: 11,
            freqs: [
                { name: "day", value: 100 },
                { name: "week", value: 200 },
                { name: "month", value: 300 },
            ],
        },
        {
            id: 12,
            freqs: [
                { name: "day", value: 100 },
                { name: "week", value: 200 },
                { name: "month", value: 300 },
            ],
        },
        {
            id: 13,
            freqs: [
                { name: "day", value: 100 },
                { name: "week", value: 200 },
                { name: "month", value: 300 },
            ],
        },
    ],
};

In this example, I would need the results:

let result = [
    { name: "day", value: 300 },
    { name: "week", value: 600 },
    { name: "month", value: 900 },
];

I've been trying for ages with a combination of filter() and reduce() methods (unsure if these are the right way), but I just can't get it - it's really a headscratcher for me! Thank you

1
  • how would you do it by pen and paper? Commented May 22, 2021 at 13:29

3 Answers 3

1

This combines all the freqs into one array then sums their values into an object and then reformats that object to be an array of objects with the name and value keys.

const arr = {"expenses":[{"id":11,"freqs":[{"name":"day","value":100},{"name":"week","value":200},{"name":"month","value":300}]},{"id":12,"freqs":[{"name":"day","value":100},{"name":"week","value":200},{"name":"month","value":300}]},{"id":13,"freqs":[{"name":"day","value":100},{"name":"week","value":200},{"name":"month","value":300}]}]};

const res = Object.entries(
  arr.expenses
    .flatMap(({ freqs }) => freqs)
    .reduce(
      (acc, { name, value }) => Object.assign(acc, { [name]: (acc[name] ?? 0) + value }),
      {}
    )
).map(([name, value]) => ({ name, value }));

console.log(res);

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

2 Comments

Amazing! You are an array master. I would never have got this. I will breakdown those functions to understand how it works. Thanks so much
Nice solution. It forced me to remove my answer.
0

If I didn't know the structure then this could be difficult. However, given your input, I think this should solve your problem.

// Your input
let arr = {
    expenses: [
        {
            id: 11,
            freqs: [
                { name: "day", value: 100 },
                { name: "week", value: 200 },
                { name: "month", value: 300 },
            ],
        },
        {
            id: 12,
            freqs: [
                { name: "day", value: 100 },
                { name: "week", value: 200 },
                { name: "month", value: 300 },
            ],
        },
        {
            id: 13,
            freqs: [
                { name: "day", value: 100 },
                { name: "week", value: 200 },
                { name: "month", value: 300 },
            ],
        },
    ],
};
// My code
let result = new Array();
// Create each object structure and push into empty result array
arr.expenses[0].freqs.forEach((item)=>result.push({name: item.name, value: 0}));
// Map through each object in arr.expenses
arr.expenses.map((object)=>{
    // Loop through each object in freqs
    object.freqs.forEach((item)=>{
        result.filter(eachItem=>{
            // Check if result objs' name matches the freqs objs' name
            if(eachItem.name==item.name){
                eachItem.value+=item.value; // Add the values
            }
        })
    });
});
// Check the output
console.log(result);

Comments

0

We want to reduce the frequences to a single element, so we can do:

let arr = { expenses: [ { id: 11, freqs: [ {name: "day", value: 100}, {name: "week", value: 200}, {name: "month", value: 300}, ], }, { id: 12, freqs: [ {name: "day", value: 100}, {name: "week", value: 200}, {name: "month", value: 300}, ], }, { id: 13, freqs: [ {name: "day", value: 100}, {name: "week", value: 200}, {name: "month", value: 300}, ], }, ], };

let result = arr.expenses.reduce((total, curr) => {
    total[0].value += curr.freqs[0].value
    total[1].value += curr.freqs[1].value
    total[2].value += curr.freqs[2].value

    return total
    }, [{name: "day", value: 0}, {name: "week", value: 0}, {name: "month", value: 0}])

console.log(result)

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.