0

I have a JS Array which also contains arrays with each holding a bunch of objects structured like below.

const arr1 = [
  [{symbol: "xy", balance: 2155113}, {symbol: "asda", balance: 21231231}],
  [{symbol: "asda", balance: 6543}, {symbol: "xy", balance: 21678}]
]

What I need, is an output array, that groups all the child arrays by the "symbol" property and adds (+) the balances together.

At the End I want to have an array like this

[
{symbol: xy, summedBalance: 213131313}, 
{symbol: yz, summedBalance: 6788767867},
]

Is this possible with normal javascript or maybe a module like lodash?

BitQueen
  • 585
  • 1
  • 6
  • 20

2 Answers2

1

Try something like this :

const arr1 = [
  [{symbol: "xy", balance: 2155113}, {symbol: "asda", balance: 21231231}],
  [{symbol: "asda", balance: 6543}, {symbol: "xy", balance: 21678}]
]

// Some variables
const knownSymbolsArr = [];
const finalArr = [];

// First degroup your array
const degroupedArr = arr1.flat();

// Iterate and sum balances
degroupedArr.forEach(el => {
  // Unknown symbol, process
  if (knownSymbolsArr.indexOf(el.symbol) === -1) {
    // Sum balances when symbol is el.symbol
    const balance = degroupedArr.reduce((acc, val) => val.symbol === el.symbol ? acc + val.balance : acc, 0);
    
    // Add symbol in our knownSymbolsArr
    knownSymbolsArr.push(el.symbol);
    
    // Add data in our final array
    finalArr.push({
      symbol: el.symbol,
      balance: balance
    });
  }
});

console.log(finalArr);
Bloodbee
  • 827
  • 8
  • 23
  • thank you, that looks quiet like my previous djungle of for loops but shows me that I wasnt that far away. Looks like it is working using your approach. Thank you for this. Could you give me a hint of where to edit the reduce function when the balance fields need to be converted to BigNumbers before adding them together? – BitQueen Dec 27 '21 at 16:29
  • It's maybe not the most efficient solution, but your array is not too big so should do the work. – Bloodbee Dec 27 '21 at 16:31
  • If you want to edit the balance, do that just in the ternary condition: val.symbol === el.symbol ? acc + val.balance (<==== edit here) : acc – Bloodbee Dec 27 '21 at 16:31
1

The solution can be broken down into two parts :

  1. Flatten the input array
  2. Group the elements of flattened array by symbol and calculate the sum.

const ar = [
  [{symbol: "xy", balance: 2155113}, {symbol: "asda", balance: 21231231}],
  [{symbol: "asda", balance: 6543}, {symbol: "xy", balance: 21678}]
]

const flattenedAr = ar.reduce((acc, curElement) => {
  acc = [...acc, ...curElement];
  return acc;
}, []);

const groupedAr = flattenedAr.reduce((group, curElement) => {

  const matchingElement = group.find(ele => ele.symbol === curElement.symbol);
  if(matchingElement) {
   matchingElement.summedBalance += curElement.balance;
  } else { 
   group.push({
     symbol: curElement.symbol,
     summedBalance: curElement.balance
   }); 
  }
   
  return group
}, [])

console.log(groupedAr)
Tyler Durden
  • 860
  • 6
  • 17