Cash Register - Array mutation [solved]

“cid” is one of my function argument and for some reason it mutates when I run the function.
I can’t figure out why… can you help please?


let changeDict = [["PENNY", 0.01], ["NICKEL", 0.05], ["DIME", 0.1], ["QUARTER", 0.25], ["ONE", 1], ["FIVE", 5], ["TEN", 10], ["TWENTY", 20], ["ONE HUNDRED", 100]];

function checkCashRegister(price, cash, cid) {

  Object.freeze(cid)
  var du = cash - price;
  var due = Math.round(du * 100) / 100;
  var change = 0;
  var cid2 = [...cid];
  var status = "";
  var changeWord = [];
  var change2 = [];
  var count = 0;
  var total=0;
  console.log(due)
  
  

  for (var i = changeDict.length-1 ; i!=-1 ; i--) {
   total += cid2[i][1];
    while (due >= changeDict[i][1] && cid2[i][1] > 0 ) {
      change += changeDict[i][1];
      due -= changeDict[i][1];
      cid2[i][1] -= changeDict[i][1];
      count +=changeDict[i][1];
      changeWord= changeDict[i][0]
      due = Math.round(due * 100) / 100
      change = Math.round(change * 100) / 100
      console.log(i,due,change,cid2[i][1])
    }

    if (count>0) {
      change2.push([changeWord,count]);
      count=0;
      changeWord = [];
    }
    console.log(total,cash,price)
    if (cash - total - price === 0 ) {
    return {status: "CLOSED", change: cid};
    }
    
    if (due === 0 ) {
    status = "OPEN";
    return {status: status , change: change2};
    }

  }
  
  if (due != 0 ) {
    return {status: "INSUFFICIENT_FUNDS", change: []};
  }
}


console.log(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 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/11.1.2 Safari/605.1.15.

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

I believe cid2 = [...cid] is a shallow copy.

Thanks. I have used .slice() to do my copy as well but I keep having the mutation… what would be the good way to do a copy of “cid” without mutation?

Slice creates a shallow copy also. You can create a new empty (let’s call it cidCopy and iterate through cid and push shallow copies of each subarray to the new cidCopy arrray if you want.

1 Like

you mean push a hard copy right?
edit: nvm, I think I know what you are saying

Also, I think .map() can make hard copies. Not sure if it’s deep or just 1 level though.

okay, yeah, .map is only 1 level deep hard. It’ll shallow copy objects and arrays.

You can use map like:

const cidCopy = cid.map(subArr => [...subArr]);

RIght, but I think a problem would still remain if subArr contained any arrays and objects. It would shallow copy those right?

You are correct. But in this specific case, subArr will not.

Right. Just trying to make sure I understand how deep certain methods of copy are. I just know it will trip me up one of these days. Like it seems the only for sure way I know to deep copy absolutely everything is to make a recursive call that digs and digs until it can’t dig any more.

It can be done imperatively also, but either would be overkill for this specific problem. Another way you can do it as long as the array/object does not contain any functions is to use JSON.parse on a stringified JSON object.

const cidCopy = JSON.parse(JSON.stringify(cid));
1 Like

I’ll have to explore that option later. It makes more sense to me to do it recursively. Though the memory consumption is probably not that great.

Got it. Thanks for the help @RandellDawson & @zapcannon99 !