Home > Mobile >  How to get optimal solution for grouping in javascript
How to get optimal solution for grouping in javascript

Time:12-28

Given the two below arrays. id in catalog and item_id in inventory arrays are same. Then category wise toys ids: 1,6,8,9,10 matches the item_id in inventory. We need to add the units in inventory for matching ids in catalog. expected output we need to return the max units of inventory (toys->335) For example, For toys: id's are 1,6,8,9,10 and matching item_id in inventory for toys are 1,9 then total units for toys is 155 180=335. For grocery: id's are 2,4,5 and matching item_id in inventory for toys are 2,5 then total units for grocery is 200 10=210.... For medical: id's are 3,7 and matching item_id in inventory for toys are 3 then total units for medical is 150....

Max units for catalog category is toys i.e 335 should be returned.

let catalog = [
  { id: 1, title: "obj 01", category: "toys" },
  { id: 2, title: "obj 02", category: "grocery" },
  { id: 3, title: "obj 03", category: "medical" },
  { id: 4, title: "obj 04", category: "grocery" },
  { id: 5, title: "obj 05", category: "grocery" },
  { id: 6, title: "obj 06", category: "toys" },
  { id: 7, title: "obj 07", category: "medical" },
  { id: 8, title: "obj 08", category: "toys" },
  { id: 9, title: "obj 09", category: "toys" },
  { id: 10, title: "obj 10", category: "toys" }
];

let inventory = [
  { item_id: 1, units: 155 },
  { item_id: 2, units: 200 },
  { item_id: 3, units: 150 },
  { item_id: 5, units: 10 },
  { item_id: 9, units: 180 }
];

Max units for catalog category is toys i.e 335 should be returned.

CodePudding user response:

For grouping, you can use a Map or a plain object. Give each group a starting sum of 0, and then iterate the data and add the units to the corresponding group. For looking up the units by id, also make a lookup object for the inventory.

function getMaxSumUnits(catalog, inventory) {
    const invMap = new Map(inventory.map(o => [o.item_id, o.units]));
    const catMap = Object.fromEntries(catalog.map(({category}) => [category, 0]));
    for (const o of catalog) catMap[o.category]  = invMap.get(o.id) ?? 0;
    return Math.max(...Object.values(catMap));
}

const catalog = [
  { id: 1, title: "obj 01", category: "toys" },
  { id: 2, title: "obj 02", category: "grocery" },
  { id: 3, title: "obj 03", category: "medical" },
  { id: 4, title: "obj 04", category: "grocery" },
  { id: 5, title: "obj 05", category: "grocery" },
  { id: 6, title: "obj 06", category: "toys" },
  { id: 7, title: "obj 07", category: "medical" },
  { id: 8, title: "obj 08", category: "toys" },
  { id: 9, title: "obj 09", category: "toys" },
  { id: 10, title: "obj 10", category: "toys" }
];

const inventory = [
  { item_id: 1, units: 155 },
  { item_id: 2, units: 200 },
  { item_id: 3, units: 150 },
  { item_id: 5, units: 10 },
  { item_id: 9, units: 180 }
];

console.log(getMaxSumUnits(catalog, inventory));

CodePudding user response:

You can use a function that receives the category, catalog and inventory as follows or you can choose to compute a summary including all categories as will be shown shortly in a second demo.

const 
    catalog = [
      { id: 1, title: "obj 01", category: "toys" },
      { id: 2, title: "obj 02", category: "grocery" },
      { id: 3, title: "obj 03", category: "medical" },
      { id: 4, title: "obj 04", category: "grocery" },
      { id: 5, title: "obj 05", category: "grocery" },
      { id: 6, title: "obj 06", category: "toys" },
      { id: 7, title: "obj 07", category: "medical" },
      { id: 8, title: "obj 08", category: "toys" },
      { id: 9, title: "obj 09", category: "toys" },
      { id: 10, title: "obj 10", category: "toys" }
    ],

    inventory = [
      { item_id: 1, units: 155 },
      { item_id: 2, units: 200 },
      { item_id: 3, units: 150 },
      { item_id: 5, units: 10 },
      { item_id: 9, units: 180 }
    ],

    getMaxProd = ( prod, c, i ) => i.filter(({item_id}) => c.find(({id}) => id === item_id).category === prod)
        .reduce((acc,{units}) => acc   units, 0);
    
    
console.log( getMaxProd('toys', catalog, inventory) );
console.log( getMaxProd('grocery', catalog, inventory) );
console.log( getMaxProd('medical', catalog, inventory) );

Alternatively .....

Summarize as follows:

const 
    catalog = [
      { id: 1, title: "obj 01", category: "toys" },
      { id: 2, title: "obj 02", category: "grocery" },
      { id: 3, title: "obj 03", category: "medical" },
      { id: 4, title: "obj 04", category: "grocery" },
      { id: 5, title: "obj 05", category: "grocery" },
      { id: 6, title: "obj 06", category: "toys" },
      { id: 7, title: "obj 07", category: "medical" },
      { id: 8, title: "obj 08", category: "toys" },
      { id: 9, title: "obj 09", category: "toys" },
      { id: 10, title: "obj 10", category: "toys" }
    ],

    inventory = [
      { item_id: 1, units: 155 },
      { item_id: 2, units: 200 },
      { item_id: 3, units: 150 },
      { item_id: 5, units: 10 },
      { item_id: 9, units: 180 }
    ],

    catSummary = [...new Set(catalog.map(item => item.category))]
        .map(
            cat => [
                cat,
                inventory
                    .filter(({item_id}) => catalog.find(({id}) => id === item_id).category === cat)
                    .reduce((acc,{units}) => acc   units, 0)
            ]
        );
    
    
console.log( catSummary );
console.log( Object.fromEntries(catSummary) ); //OR

  • Related