设计一个收银程序 checkCashRegister() ,其把购买价格(price)作为第一个参数 , 付款金额 (cash)作为第二个参数, 和收银机中零钱 (cid) 作为第三个参数.
cid 是一个二维数组,存着当前可用的找零.
当收银机中的钱不够找零时返回字符串 "Insufficient Funds". 如果正好则返回字符串 "Closed".
否则, 返回应找回的零钱列表,且由大到小存在二维数组中.
var denom = [
{ name: 'ONE HUNDRED', val: 100.00},
{ name: 'TWENTY', val: 20.00},
{ name: 'TEN', val: 10.00},
{ name: 'FIVE', val: 5.00},
{ name: 'ONE', val: 1.00},
{ name: 'QUARTER', val: 0.25},
{ name: 'DIME', val: 0.10},
{ name: 'NICKEL', val: 0.05},
{ name: 'PENNY', val: 0.01}
];
function checkCashRegister(price, cash, cid) {
//需要找零的钱
var change = cash - price;
//把收银台的钱求和,同时转变成一个对象
var register = cid.reduce(function(prev, curr) {
prev.total += curr[1];
prev[curr[0]] = curr[1];
return prev;
}, {total: 0});
//简单的判断
if (register.total === change) {
return 'Closed';
}
if (register.total < change) {
return 'Insufficient Funds';
}
// 循环我们之前定义的二维数组,并求出我们想要返回的面值数组
var change_arr = denom.reduce(function(prev, curr) {
var value = 0;
//把收银台里的面值从大到小的去筛选,并判断这张面值能否找零
while (register[curr.name] > 0 && change >= curr.val) {
change -= curr.val;//满足条件就扣除这么大的一张面值,好比总共找零60,先给一张50
register[curr.name] -= curr.val;//同时收银台
value += curr.val;
//熟悉的朋友知道JavaScript精度的问题,很多时候2其实是1.999999999999,所以这里处理下。
change = Math.round(change * 100) / 100;
}
// 如果value有值,就可以加入要返回的数组了,否则比较下一阶的面值
if (value > 0) {
prev.push([ curr.name, value ]);
}
return prev;
}, []);
//数组里没有值 ,或者需要找零的钱不够
if (change_arr.length < 1 || change > 0) {
return "Insufficient Funds";
}
return change_arr;
}
// Example cash-in-drawer array:
// [["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]]
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]]);