Cash Register - cid value changes after a for loop, even though I do not touch the "cid" value whatsoever

Tell us what’s happening:

I tried the immutable approach (at least I think I did) and stayed away from mutating the original “cid” value until the very end, when I needed to copy paste the cash-in-register values. But instead of getting 0.5 pennies, I get 0 pennies. I tried debugging, which led me to discover, that something in the for loop after the switch statement changes the “cid” values globally and I cannot seem to find the solution.

Your code so far


function checkCashRegister(price, cash, cid) {
  let answer = {
    status: "",
    change: []
  };
  
  const priceCopy = price;
  const cashCopy = cash;
  const cidCopy = cid;  
  
  let totalCashInRegister = 0;
  
  let change = cashCopy - priceCopy;

  for (let i = 0; i < cidCopy.length; i++) {
    totalCashInRegister += cidCopy[i][1];
  }
  
  let totalCashInRegisterCopy = totalCashInRegister;
  
  for (let i = (cidCopy.length - 1); i >= 0; i--) {
    let currentCurrencyVal = 0;
    let val = 0;
    let currencyUnit = "";
    
    switch(i) {
      case 8:
        currentCurrencyVal = 100;
        currencyUnit = "ONE HUNDRED";
        break;
      case 7:
        currentCurrencyVal = 20
        currencyUnit = "TWENTY";
        break;
      case 6:
        currentCurrencyVal = 10;
        currencyUnit = "TEN";
        break;
      case 5:
        currentCurrencyVal = 5;
        currencyUnit = "FIVE";
        break;
      case 4:
        currentCurrencyVal = 1;
        currencyUnit = "ONE";
        break;
      case 3:
        currentCurrencyVal = 0.25;
        currencyUnit = "QUARTER";
        break;
      case 2:
        currentCurrencyVal = 0.1;
        currencyUnit = "DIME";
        break;
      case 1:
        currentCurrencyVal = 0.05;
        currencyUnit = "NICKEL";
        break;
      case 0:
        currentCurrencyVal = 0.01;
        currencyUnit = "PENNY";
        break;
    }
        
    while (Number(change.toFixed(2)) >= currentCurrencyVal && cidCopy[i][1] >= currentCurrencyVal) {
      change -= currentCurrencyVal;
      change = Number(change.toFixed(2));
      
      cidCopy[i][1] -= currentCurrencyVal;
      cidCopy[i][1] = Number(cidCopy[i][1].toFixed(2));
      
      val += currentCurrencyVal;
      val = Number(val.toFixed(2));
    }
        
    if (val !== 0) {
      answer.change = [...answer.change, [currencyUnit, val]];
    }
  }  
  
  if (change > 0) {
    answer.status = "INSUFFICIENT_FUNDS";
    answer.change = [];
  }
  
  if (change === 0) {
    let newVal = 0;
    for (let i = 0; i < answer.change.length; i++) {
      newVal += answer.change[i][1];
      newVal = Number(newVal.toFixed(2));
    }
    
    if (newVal == totalCashInRegisterCopy) {
      answer.status = "CLOSED";
      answer.change = cid;
      //  answer.change[0][1] = 0.5; <-- quick fix
    }
    
    else {
      answer.status = "OPEN";
    }
  }
  
  console.log(answer);
  
  // Here is your change, ma'am.
  return answer;
}

// Example cash-in-drawer array:
// [["PENNY", 1.01],
// ["NICKEL", 2.05],
// ["DIME", 3.1],
// ["QUARTER", 4.25],
// ["ONE", 90],
// ["FIVE", 55],
// ["TEN", 20],
// ["TWENTY", 60],
// ["ONE HUNDRED", 100]]

checkCashRegister(19.5, 20, [["PENNY", 0.5], ["NICKEL", 0], ["DIME", 0], ["QUARTER", 0], ["ONE", 0], ["FIVE", 0], ["TEN", 0], ["TWENTY", 0], ["ONE HUNDRED", 0]]);

Your browser information:

User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36.

Link to the challenge:
https://learn.freecodecamp.org/javascript-algorithms-and-data-structures/javascript-algorithms-and-data-structures-projects/cash-register/

At first I attempted with the spread operator, but the problem was still the same. Also tried the slice method, but it did not change anything either.

I have a jsbin link where I tried debugging this: https://jsbin.com/bapamogoce/1/edit?js,console

For some reason, it still mutates the original array without me ever touching it

I’m having a similar issue. Did you ever reach a resolution?

I also am using slice to make a “copy” of cid, and not referencing cid at all in my for loop. My console.logs show that cid goes into the loop normal, but comes out altered.

that is because the spread operator only copies the first level of the array and nothing beyond
(the rest are memory pointers so you end up changing the original array)

I suggest you just make a loop to copy the elements one by one (you can use spread at the lowest level)

1 Like

read the response above…

Would Object.assign() work to copy an array to a variable? Saw this in another thread, and was wondering if it would work here.

edit: nvm, I think it only works on objects

Excellent! That fixed it! Thank you so much…that was the only thing holding me back from passing all tests. I remember reading something about the spread operator only copying the first level, but never connected the dots.

1 Like

assign() can’t be used to make a deep copy either as it is only doing a shallow assignment of first level props. (I tried it to double check)

Thanks for checking. I figured. Plus, it’s mainly for objects anyways.