Skip to content
Advertisement

looping through an array of objects that contains three key, value pairs

I have these objects, which could be in an array, like in the example or a database:

[  
  { "payer": "DANNON", "points": 1000, "timestamp": "2020-11-02T14:00:00Z" }
  { "payer": "UNILEVER", "points": 200, "timestamp": "2020-10-31T11:00:00Z" } 
  { "payer": "DANNON", "points": -200, "timestamp": "2020-10-31T15:00:00Z" } 
  { "payer": "MILLER COORS", "points": 10000, "timestamp": "2020-11-01T14:00:00Z" } 
  { "payer": "DANNON", "points": 300, "timestamp": "2020-10-31T10:00:00Z" }
]

I want to subtract a total of { "points": 5000 } as an example from the points values of these objects starting with the oldest points based on timestamp, keep in mind no payer’s points to go negative. then I want to return how much each payer’s points were used. The expected result looks like this:

[
  { "payer": "DANNON", "points": -100 },
  { "payer": "UNILEVER", "points": -200 },
  { "payer": "MILLER COORS", "points": -4,700 }
]

My initial solution was:

  1. To sort the array based on the oldest timestamp
  2. Create a new object to store the number of points used from each payer
  3. Looping through the sorted array and subtracting the points from each payer and storing the number of points used in that new object.
  4. push all new objects to an array and return it. This solution made sense to me but I couldn’t implement it, I kept on having unexpected results until my brain froze and I can’t think anymore.

This is an apprenticeship interview question. I thought it was easy at the beginning, but then after spending hours without solving it, I’m thinking am I an imposter? or is this question a tricky one?

Thank you for sharing your knowledge and experience and helping me out. I appreciate it!

Advertisement

Answer

I just implemented those steps you listed in your questions and made a function subtract(payers, subtractingPoints):

that given an array of payers and a number of points to substract, it will sort the array by timestamp and will take away those points from each payer until that number is reached or array length has been hit before all the points could be substracted.

The function returns an array of objects each one saying how much points were taken by each single payer (grouped).

let payers = [  
  {
    "payer": "DANNON",
    "points": 1000,
    "timestamp": "2020-11-02T14:00:00Z"
  },
  {
    "payer": "UNILEVER",
    "points": 200,
    "timestamp": "2020-10-31T11:00:00Z"
  },
  {
    "payer": "DANNON",
    "points": -200,
    "timestamp": "2020-10-31T15:00:00Z"
  }, 
  {
    "payer": "MILLER COORS",
    "points": 10000,
    "timestamp": "2020-11-01T14:00:00Z"
  }, 
  {
    "payer": "DANNON",
    "points": 300,
    "timestamp": "2020-10-31T10:00:00Z"
  }
];

const o = subtract(payers, 5000);
console.log(o);

function subtract(payers, subtractingPoints){

  payers.sort(function(x, y){
    date1 = new Date(x.timestamp);
    date2 = new Date(y.timestamp);
    return date1 - date2 ;
  });
  
  payersAccounted = {};
  let i = 0;
  while(subtractingPoints > 0 && i < payers.length){
    
    const currentPayer = payers[i].payer;
    
    let pointsTookAway =
      Math.min(payers[i].points, subtractingPoints);
    
    if( !(currentPayer in payersAccounted) )
      payersAccounted[currentPayer] = pointsTookAway;
    else
      payersAccounted[currentPayer] += pointsTookAway;
      
    subtractingPoints -= pointsTookAway;
    i++;
  }
  
  let result = [];
  for (const [key, value] of Object.entries(payersAccounted)) {
    result.push( { "payer": key, "points": -1*value } );
  }
  
  return result;
}
User contributions licensed under: CC BY-SA
6 People found this is helpful
Advertisement