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

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

#1

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/


#2

The above does NOT create a copy of the cid array. If you have been following the curriculum, you will have been introduced to the slice method or the spread operator to create copies of arrays. If not, do a quick search on the curriculum for these methods/syntax.

The line above just creates another reference to the cid array. Anything you do to cidCopy directly affects cid.


#3

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


#4

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.


#5

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)


#6

read the response above…


#7

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


#8

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.


#9

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)


#10

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


#11

FYI - If you have an array that you want to deep copy, you can write the following. It is not the most efficient method, so only use it for smaller arrays.

var array = [[1,2, 3], [4, 5, 6], [7,8,9]];
var arrayCopy = JSON.parse(JSON.stringify(array));
arrayCopy[1].splice(1); // removes 5 and 6 from the 2nd sub array inside array
console.log(arrayCopy); // displays [[1,2, 3], [4], [7,8,9]]
console.log(array); // displays [[1,2, 3], [4,5, 6], [7,8,9]]