如何使用While循环执行Exact Change挑战中的步骤?

时间:2017-09-21 06:40:48

标签: javascript arrays javascript-objects

我正在研究这部分代码,以便了解“Exact Change”FreeCodeCamp问题。问题的一部分要求返回硬币和账单的变化。这意味着如果总变化为1.25美元,它会检查自动提款机是否有足够的变化返回,如果是,它将返回“$ 1”美元账单和的变化季度“硬币。

换句话说,我需要检查总变化是否高于货币面额,例如“一百”账单,“二十”账单,“十”账单,“五”账单,“一”账单, “四分之一”硬币,等等......如果是这样,那么我将需要从总变化和现金机器的变更面额中减去货币面额。

这是我的代码:

function checkCashRegister(price, cash, cid) {
  
  var total = cash - price;
  
  var denom = [{name:"ONE HUNDRED", val:100.00}, {name:"TWENTY", val:20}, {name:"TEN", val:10}, {name:"FIVE", val:5}, {name:"ONE", val:1}, {name:"QUARTER", val:0.25}, {name:"DIME", val:0.1}, {name:"NICKEL", val:0.05}, {name:"PENNY", val:0.01}];
  
  var changeleft = total;
 
 //Reduce method use on the denom array. The "[]" is the first argument of the accum parameter in reduce function method. Next, another parameter, represent each object in denom array. Index iterate through the array.
  var result = denom.reduce(function(accum, next, index) {
  	var totalcharge = 0.00;
    
    if(changeleft >= next.val) {//check if total change is higher than the money denomations in denom array
    	while(changeleft >= next.val && cid[index][1] >= next.val) {//check if total change is higher and if the money values from cid array is higher
      	totalcharge += next.val;//add the money value from denom array to totalcharge
      	changeleft -= next.val;//subtract total from total change
      	cid[index][1] -= next.val;//subtract total from cash machine's money
      }
      accum.push([next.name, totalcharge]);//push the name and the total to accum array.
      return accum;
    } else { //why is it necessary?
    	return accum;
    }
  }, []);
    
}

console.log(checkCashRegister(19.50, 20.00, [["PENNY", 1.01], ["NICKEL", 2.05], ["DIME", 3.10], ["QUARTER", 4.25], ["ONE", 90.00], ["FIVE", 55.00], ["TEN", 20.00], ["TWENTY", 60.00], ["ONE HUNDRED", 100.00]]));

有几件事我不明白或不想看。我不明白为什么reduce方法中的 else语句是必要的。我注意到没有else语句,它会返回一个错误,说它无法读取未定义的属性“push”。

我希望看到的是控制台中详细说明reduce方法如何工作的步骤。例如,我可以使用此行:console.log( $ {num}%$ {i} === $ {num%i} );来自另一个question,其中最佳答案解释如何看到这些步骤以了解它的工作原理。那么如何编写一行来列出console.log中的步骤呢?我试过这样做,但它一直在继续,所以我不得不强制关闭浏览器,以停止进程。

2 个答案:

答案 0 :(得分:0)

else是没有必要但重要的是返回其他内容为下一次迭代将是未定义的,第一次迭代中返回的对象将在变量accum的下一次迭代中使用

答案 1 :(得分:0)

Array.reduce遍历数组的每个索引并应用作为第一个参数传递的函数。每次迭代都使用从该函数返回的值(在前一次迭代中)作为该函数的第一个参数。第一次迭代使用reduce()函数的第二个参数。

在此示例中,accum是每次迭代返回的值。因此,如果没有else分支,则不返回任何内容,因此在下一次迭代中将accum未定义。

您可以将return语句移到if/else分支之外,以完全删除else分支。

这是没有else语句的代码:

function checkCashRegister(price, cash, cid) {
  const denom = [{name: "ONE HUNDRED", val: 100.00}, {name: "TWENTY", val: 20}, {name: "TEN", val: 10}, {name: "FIVE", val: 5}, {name: "ONE", val: 1}, {name: "QUARTER", val: 0.25}, {name: "DIME", val: 0.1}, {name: "NICKEL", val: 0.05}, {name: "PENNY", val: 0.01}]

  let changeleft = cash - price
  return denom.reduce(function(accum, next, index) {
    let totalcharge = 0.00
    if(changeleft >= next.val) {
      while(changeleft >= next.val && cid[index][1] >= next.val) {
        totalcharge += next.val
        changeleft -= next.val
        cid[index][1] -= next.val
      }
      accum.push([next.name, totalcharge])
    }
    return accum
  }, [])

}

console.log(checkCashRegister(19.50, 20.00, [["PENNY", 1.01], ["NICKEL", 2.05], ["DIME", 3.10], ["QUARTER", 4.25], ["ONE", 90.00], ["FIVE", 55.00], ["TEN", 20.00], ["TWENTY", 60.00], ["ONE HUNDRED", 100.00]]))