mr.snobot
mr.snobot

Reputation: 3

How do I return the sum of the duplicate values in an array of objects plus return the values of the non-duplicate values?

First question on here so please feel free to point out what I should be doing differently or if there are other threads I should refer to.

I have array of objects that look like this:

const fetchResults = [ {
  date: '03/20/2020', symbol: 'TLTE', quantity: 100, amount: 3570,
}, {
  date: '03/20/2020', symbol: 'GE', quantity: 100, amount: 10000,
}, {
  date: '03/20/2020', symbol: 'AAPL', quantity: 50, amount: 22222,
}, {
  date: '03/20/2020', symbol: 'TLTE', quantity: 4, amount: 161.02,
}, {
  date: '03/20/2020', symbol: 'TLTE', quantity: 281, amount: 10034.51,
}, {
  date: '03/21/2020', symbol: 'TLTE', quantity: 200, amount: 8000,
} ]

I need a payload that returns the sum of the quantity and amount for each trade date and symbol. Specifically, in this example, it would total the quantity and amount for the 3 objects with TLTE and 3/20/20. The payload results would look like this:

const payloadResults = [ {
  date: '03/20/2020', symbol: 'GE', quantity: 100, amount: 10000,
}, {
  date: '03/20/2020', symbol: 'AAPL', quantity: 50, amount: 22222,
}, {
  date: '03/20/2020', symbol: 'TLTE', quantity: 385, amount: 13765.53,
}, {
  date: '03/21/2020', symbol: 'TLTE', quantity: 200, amount: 8000,
} ]

Here's the code I've tried:

const fetchResults = [ {
    trade_date: '03/20/2020', symbol: 'TLTE', quantity: 100, amount: 3570,
  }, {
    trade_date: '03/20/2020', symbol: 'GE', quantity: 100, amount: 10000,
  }, {
    trade_date: '03/20/2020', symbol: 'AAPL', quantity: 50, amount: 22222,
  }, {
    trade_date: '03/20/2020', symbol: 'TLTE', quantity: 4, amount: 161.02,
  }, {
    trade_date: '03/20/2020', symbol: 'TLTE', quantity: 281, amount: 10034.51,
  }, {
    trade_date: '03/21/2020', symbol: 'TLTE', quantity: 200, amount: 8000,
  } ]

  const payloadResults = []
  const uniqueTradeDates = Array.from(new Set(fetchResults.map(({ trade_date }) => trade_date)))
  const uniqueSecurityIds = Array.from(new Set(fetchResults.map(({ symbol }) => symbol)))
  for (const td of uniqueTradeDates) {
    for (const s of uniqueSecurityIds) {
      const results = fetchResults.filter((r) => r.symbol === s && r.trade_date === td)
      if (results.length > 0) {
        const totalQuantity = results.reduce((a, b) => a + b.quantity, 0)
        const totalAmount = results.reduce((a, b) => a + b.amount, 0)
        payloadResults.push({
          trade_date: td, symbol: s, quantity: totalQuantity, amount: totalAmount,
        })
      }
    }
  }
  console.log(payloadResults)

Thanks for your help!

Upvotes: 0

Views: 133

Answers (3)

Saadi Toumi Fouad
Saadi Toumi Fouad

Reputation: 2829

var fetchResults = [ 
  {date: '03/20/2020', symbol: 'TLTE', quantity: 100, amount: 3570},
  {date: '03/20/2020', symbol: 'GE', quantity: 100, amount: 10000},
  {date: '03/20/2020', symbol: 'AAPL', quantity: 50, amount: 22222},
  {date: '03/20/2020', symbol: 'TLTE', quantity: 4, amount: 161.02},
  {date: '03/20/2020', symbol: 'TLTE', quantity: 281, amount: 10034.51},
  {date: '03/21/2020', symbol: 'TLTE', quantity: 200, amount: 8000}
];

function sumResults(a) {
  var b = {}, c = [], d = 0;
  a.forEach(function(e) {
    var f = e.date + e.symbol;
    if(f in b) c[b[f]].quantity += e.quantity,
      c[b[f]].amount += e.amount;
    else b[f] = d++, c.push(e);
  });
  return c;
}

console.log(sumResults(fetchResults));

Upvotes: 0

collapsar
collapsar

Reputation: 17238

Reorganize the source array into a nested 2-level dictionary and compute the totals by iterating over dictionary entries:

const fetchResults = [ {
        date: '03/20/2020', symbol: 'TLTE', quantity: 100, amount: 3570,
    }, {
        date: '03/20/2020', symbol: 'GE', quantity: 100, amount: 10000,
    }, {
        date: '03/20/2020', symbol: 'AAPL', quantity: 50, amount: 22222,
    }, {
        date: '03/20/2020', symbol: 'TLTE', quantity: 4, amount: 161.02,
    }, {
        date: '03/20/2020', symbol: 'TLTE', quantity: 281, amount: 10034.51,
    }, {
        date: '03/21/2020', symbol: 'TLTE', quantity: 200, amount: 8000,
    }
];

function aggregate () {
    let dict_aggregate = {}
      ;
      
    fetchResults.forEach ( (item, idx) => {
        if (dict_aggregate[item.date] === undefined) {
            dict_aggregate[item.date] = {};
        }
        if (dict_aggregate[item.date][item.symbol] === undefined) {
            dict_aggregate[item.date][item.symbol] = { quantity: 0, amount: 0.0 };
        }
        dict_aggregate[item.date][item.symbol].quantity  += item.quantity;
        dict_aggregate[item.date][item.symbol].amount    += item.amount;
    });
    
    let a_results = [];
    for (let [s_keyDate, dict_bySymbol] of Object.entries(dict_aggregate)) {
        for (let [s_keySymbol, dict_totals] of Object.entries(dict_bySymbol)) {
            a_results.push ({
                date:       s_keyDate
              , symbol:     s_keySymbol
              , quantity:   dict_totals.quantity
              , amount:     dict_totals.amount
            });
        }
    }
    
    return a_results;
}

let payloadResults = aggregate()
  ;

console.log(JSON.stringify(payloadResults));


 

Upvotes: 0

epascarello
epascarello

Reputation: 207511

Just a simple loop with reduce to make up an object that has a key made up of the fields that make them duplicates. In this case it is the symbol and the date. So loop over making a key with those two fields. Check to see if we have seen it before, if we have, we just update the quantity and amount. If not, we just add the record.

const fetchResults = [ {
  date: '03/20/2020', symbol: 'TLTE', quantity: 100, amount: 3570,
}, {
  date: '03/20/2020', symbol: 'GE', quantity: 100, amount: 10000,
}, {
  date: '03/20/2020', symbol: 'AAPL', quantity: 50, amount: 22222,
}, {
  date: '03/20/2020', symbol: 'TLTE', quantity: 4, amount: 161.02,
}, {
  date: '03/20/2020', symbol: 'TLTE', quantity: 281, amount: 10034.51,
}, {
  date: '03/21/2020', symbol: 'TLTE', quantity: 200, amount: 8000,
} ]

// Object values returns the values of all the properties in an object
const results = Object.values(
  // we are going to take our array and create a lookup object using reduce
  fetchResults.reduce((obj, data) => {
    // generate the key for our lookup object
    const key = data.symbol + data.date
    // check to see if the result exists yet
    const dayResult = obj[key]
    // if it exists we updated the record values
    if (dayResult) {
      dayResult.quantity += data.quantity
      dayResult.amount += data.amount    
    } else {
      // if it does not exist we copy the record into the  key we made
      obj[key] = { ...data }
    }
    // return our lookup data
    return obj
  }, {})
)

console.log(results)

Upvotes: 1

Related Questions