skip to Main Content

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


  1. You can just use flat() to flatten the array. Then you need to seed/ initialized reduce() 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 using Object.entries().

    Note I am also ussing a nullish coalescing assignment as I think this is more readable then working with falsy values.

    const input = [
      [{
        product: "a",
        volume: 3
      }, {
        product: "b",
        volume: 7
      }, {
        product: "c",
        volume: 5
      }],
      [{
        product: "a",
        volume: 8
      }, {
        product: "b",
        volume: 10
      }, {
        product: "c",
        volume: 4
      }]
    ];
    const aggregated = input.flat()
      .reduce((acc, i) => {
        acc[i.product] = (acc[i.product] ??= 0) + i.volume;
        return acc;
      }, {});
    
    const output = Object.entries(aggregated).map(([product, volume]) => ({ product, volume }));
    
    console.log(output)
    Login or Signup to reply.
  2. let 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}]]
    
    
    let SingleArray =  products.flat()
    function Customfun(){
        let map = new Map();
        let type = "";
        for(let obj of SingleArray){
            if(map.has(obj.product)){
               let vol = map.get(obj.product)
               map.set(obj.product,obj.volume+vol);
            }
            else{
                map.set(obj.product,obj.volume);
            }
        }
    
        let ProductsList = [];
        for(let [key,val] of map.entries()){
            ProductsList = [...ProductsList,{product:key, volume:val}]
        }
        
        return ProductsList;
    }
    console.log(Customfun())
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search