Home > Enterprise >  How do I organize an Array of objects according to the sum of its attributes?
How do I organize an Array of objects according to the sum of its attributes?

Time:05-20

I’m developing the backEnd part for a selling app in which I have 2 Array of Objects, one got the sellers' name, and the other has the monthly sales. I was told by my superiors to order the Array of names from the one that made the most sales to the one that made the least ( from highest to lowest ) using the data from the array which contains the sales, basically making a summation of the key => quantity. I’m not sure how to do it, I tried to use a Reduce method with the sales of each seller but I can’t think how to compare them to reorganize the Array. The code is:

const sellers= [{id:1,name: 'juan', age: 23},{id:2,name: 'adrian', age: 32},{id:3,name: 'apolo', age: 45}];

const sales= [{equipo: 'frances', sellerId: 2, quantity: 234},{equipo: 'italiano', sellerId: 3, quantity: 24},{equipo: 'polaco', sellerId: 1, quantity: 534},{equipo: 'frances', sellerId: 2, quantity: 1234},{equipo: 'frances', sellerId: 3, quantity: 2342}];

This is what I have already tried:

const bestSellers= () => {
  sales.reduce((sum, value) => ( value.sellerId == 1 ? sum   value.area : sum), 0); }

The final result should look like this:

const sellers= [{id:3,name: 'apolo', age: 45},{id:2,name: 'adrian', age: 32},{id:1,name: 'juan', age: 23}]

CodePudding user response:

You're trying to do two things here.

  1. Find the total sales for each seller.
  2. Sort the total sales for each seller.

Inside my sort function you can see I am filtering all of the sales by the seller.

Once I have just the sales for one seller I use the reduce method to sum the quantity of their sales into an easy to use number.

Then I'm comparing the previous sellers quantity to the current sellers quantity to re-order them using the sort method.

I encourage you to read the documentation of the methods used so you understand what is happening at each step.

Methods used: Sort Filter Reduce

const sellers = [{
  id: 1,
  name: 'juan',
  age: 23
}, {
  id: 2,
  name: 'adrian',
  age: 32
}, {
  id: 3,
  name: 'apolo',
  age: 45
}];

const sales = [{
  equipo: 'frances',
  sellerId: 2,
  quantity: 234
}, {
  equipo: 'italiano',
  sellerId: 3,
  quantity: 24
}, {
  equipo: 'polaco',
  sellerId: 1,
  quantity: 534
}, {
  equipo: 'frances',
  sellerId: 2,
  quantity: 1234
}, {
  equipo: 'frances',
  sellerId: 3,
  quantity: 2342
}];

const expected = [{
  id: 3,
  name: 'apolo',
  age: 45
}, {
  id: 2,
  name: 'adrian',
  age: 32
}, {
  id: 1,
  name: 'juan',
  age: 23
}]

const result = sellers.sort((a, b) => {
  totalA = sales.filter(sale => sale.sellerId === a.id).reduce((acc, val) => acc   val.quantity, 0)
  totalB = sales.filter(sale => sale.sellerId === b.id).reduce((acc, val) => acc   val.quantity, 0)
  return totalB - totalA
})

// Check we get what we expect
console.log(JSON.stringify(expected) === JSON.stringify(result))

CodePudding user response:

First, reduce the sales array to the sum of quantity for each seller, sort this list and then map to the respective seller from the sellers array.

const sellers= [{id:1,name: 'juan', age: 23},{id:2,name: 'adrian', age: 32},{id:3,name: 'apolo', age: 45}];

const sales= [{equipo: 'frances', sellerId: 2, quantity: 234},{equipo: 'italiano', sellerId: 3, quantity: 24},{equipo: 'polaco', sellerId: 1, quantity: 534},{equipo: 'frances', sellerId: 2, quantity: 1234},{equipo: 'frances', sellerId: 3, quantity: 2342}];

const bestSellers = (sellers, sales) => {
  let res = sales.reduce((result, sale) => {
    // Check if seller is already added in result
    const obj = result.find(s => s.sellerId === sale.sellerId);
    if (obj) {
      // If seller already added then increase it's quantity
        obj.quantity  = sale.quantity;
    } else {
      // If seller not added, add seller in result
        result.push({ sellerId: sale.sellerId, quantity: sale.quantity });
    }
    return result;
  }, []);
    
  // Sort result by quantity in decreasing order 
  res.sort((a,b) => b.quantity - a.quantity);
  
  // Map each sale to the seller
  res = res.map(s => sellers.find(seller => seller.id === s.sellerId));
    
  return res;
}

const result = bestSellers(sellers, sales);
console.log(result);

CodePudding user response:

you can do that:

const
  sellers = 
    [ { id: 1, name: 'juan',   age: 23 } 
    , { id: 2, name: 'adrian', age: 32 } 
    , { id: 3, name: 'apolo',  age: 45 } 
    ] 
, sales = 
    [ { equipo: 'frances',  sellerId: 2, quantity:  234 } 
    , { equipo: 'italiano', sellerId: 3, quantity:   24 } 
    , { equipo: 'polaco',   sellerId: 1, quantity:  534 } 
    , { equipo: 'frances',  sellerId: 2, quantity: 1234 } 
    , { equipo: 'frances',  sellerId: 3, quantity: 2342 } 
    ];


sellers.forEach( ({id},i,all) => // add a sum attribute 
  {
  all[i].sum = sales
                .filter(({sellerId})=>sellerId===id)
                .reduce((sum,{quantity})=>sum quantity,0)
  });

sellers
  .sort( (a,b) => b.sum - a.sum)                 
  .forEach((seller,i,all) => delete seller.sum ) // remove the sum

console.log( sellers )
.as-console-wrapper {max-height: 100% !important;top: 0;}
.as-console-row::after {display: none !important;}

or:

const
  sellers = 
    [ { id: 1, name: 'juan',   age: 23 } 
    , { id: 2, name: 'adrian', age: 32 } 
    , { id: 3, name: 'apolo',  age: 45 } 
    ] 
, sales = 
    [ { equipo: 'frances',  sellerId: 2, quantity:  234 } 
    , { equipo: 'italiano', sellerId: 3, quantity:   24 } 
    , { equipo: 'polaco',   sellerId: 1, quantity:  534 } 
    , { equipo: 'frances',  sellerId: 2, quantity: 1234 } 
    , { equipo: 'frances',  sellerId: 3, quantity: 2342 } 
    ] 

// compute all the sum in a new Sums object:
const Sums = sales.reduce((sum,{sellerId : id, quantity}) =>
  ( sum[id] ??= 0, sum[id]  = quantity , sum ), {} )

sellers .sort( (a,b) => Sums[b.id] - Sums[a.id])

console.log( sellers )
.as-console-wrapper {max-height: 100% !important;top: 0;}
.as-console-row::after {display: none !important;}

CodePudding user response:

You can do:

const sellers = [{ id: 1, name: 'juan', age: 23 },{ id: 2, name: 'adrian', age: 32 },{ id: 3, name: 'apolo', age: 45 },]
const sales = [{ equipo: 'frances', sellerId: 2, quantity: 234 },{ equipo: 'italiano', sellerId: 3, quantity: 24 },{ equipo: 'polaco', sellerId: 1, quantity: 534 },{ equipo: 'frances', sellerId: 2, quantity: 1234 },{ equipo: 'frances', sellerId: 3, quantity: 2342 },]

const salesHash = sales.reduce((a, { sellerId, quantity }) => 
  (a[sellerId] = (a[sellerId] || 0)   quantity, a), {})

const result = sellers.sort((a, b) => 
  salesHash[b.id] - salesHash[a.id])

console.log(result)
.as-console-wrapper { max-height: 100% !important; top: 0; }

  • Related