I have an array in this form:
const products =
[{product: "a", volume: 3}, {product: "b", volume: 7}, {product: "c", volume: 5}],
[{product: "a", volume: 8}, {product: "b", volume: 10}, {product: "c", volume: 4}]
and I need to sum them and make sure the volumes for each product are not more than in another object with the same structure:
const ProductLimits: ProductVolumes[] = [{product: "a", volume: 10}, {product: "b", volume: 22}, {product: "c", volume: 12}]
Have used
products.flatMap(x => x.map(y => {
return { product: y.product, volume: y.volume }}));
which flattens the first array of arrays to a single array:
[{product: "a", volume: 3}, {product: "b", volume: 7}, {product: "c", volume: 5},
{product: "a", volume: 8}, {product: "b", volume: 10}, {product: "c", volume: 4}]
Then, in order to do the summing, I’m doing
.reduce(acc: IInterface, i) => {
acc[i.product] = acc[i.product] || 0) + i.volume;
return acc;
});
using
interface IInterface {
product: string;
volume: number;
[product: string]: any;
}
since Typescript demands an index signature.
However the problem is the reduce is returning a correct list of products except for the first one, where after 3 iterations it has:
product: "a"
volume: 3
b: 7
c: 5
The issue is clearly with the structure of the first value of acc.
Any ideas on how to fix that first iteration or of a better approach?
2
Answers
You can just use
flat()
to flatten the array. Then you need to seed/ initializedreduce()
to an empty object{}
, then the aggregation should work (you need to fix that missing bracket!). Last but not least you just need to map the aggregated values into the desired target structure usingObject.entries()
.Note I am also ussing a nullish coalescing assignment as I think this is more readable then working with falsy values.