如何在循环中找到对象数组的总和值?

时间:2016-05-25 10:13:56

标签: javascript arrays loops object

根据我对问题的描述,我不确定我的问题的措辞是否准确,所以如果它更准确,请编辑。

我正在尝试建立一个印花税计算器来改善我的JS,我有一系列具有不同“带”和“百分比”的对象,我用它来根据用户输入计算税额。我附上了一张图片以便更好地理解

enter image description here

我正在显示表格中每个波段的税额,我试图通过查找“TAX”列中所有值的总和来查找总税额。

目前它只显示最高值。

我已经尝试了所有可以解决的问题但没有任何工作,我该如何解决这个问题呢?

这是我的代码,

 $(function (jQuery) {

     (function stampDutyCalculator() {

     var taxbands = [
         {
             min: 0,
             max: 125000,
             percent: 0
         },
         {
             min: 125000,
             max: 250000,
             percent: 0.02
         },
         {
             min: 250000,
             max: 925000,
             percent: 0.05
         },
         {
             min: 925000,
             max: 1500000,
             percent: 0.1
         },
         {
             min: 1500000,
             max: null,
             percent: 0.12
         }
     ];

     var secondTaxbands = [
         {
             min: 0,
             max: 125000,
             percent: 0.03
         },
         {
             min: 125000,
             max: 250000,
             percent: 0.05
         },
         {
             min: 250000,
             max: 925000,
             percent: 0.08
         },
         {
             min: 925000,
             max: 1500000,
             percent: 0.13
         },
         {
             min: 1500000,
             max: null,
             percent: 0.15
         }
     ];

     var tableRow = "<tr><td>{taxband}</td><td>{percent}</td><td>{taxable}</td><td class='tax'>{TAX}</td></tr>", 
         table = $("#explained-table"),
         results = $("#results"),
         effectiveRate = $("#effective-rate");

         $('#calculate').on('click', function calculateButton() {
             if ($("#input-value").val() !== '') {  
                calculateStampDuty();
             }
         });

         function calculateStampDuty() {

            var bands = taxbands,        
                userInput = parseInt($("#input-value").val(), 10), 
                row;

            if ($('#second-home').is(':checked')) { 
                bands = secondTaxbands;
            }

            if (table.length) {  
                table.find("tr:gt(0)").remove(); 
            }

            var taxableSum = function (x, y) { 
                var maxBand = (x !== null) ? Math.min(x, userInput) : maxBand = userInput; 
                return maxBand - y;
            },
                TAX = function (taxablesum, x) { 
                return (taxablesum * x).toFixed(2);
            },
                effectiverate = function(tax) {
                    return Math.round(tax / userInput * 100).toFixed(1);
            },  
                numberWithCommas = function (x) {
                var parts = x.toString().split(".");
                parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",");
                return parts.join(".");
            };

                        for (var i = 0; i < bands.length; i++) { //for loop to loop through array of objects

            var min = bands[i].min, //variables to be used as arguments in functions above, not best practice to declare functions in loop
                max = bands[i].max,
                pct = bands[i].percent,
                taxablesum = taxableSum(max, min),
                tax = TAX(taxablesum, pct),
                eRate = effectiverate(tax);

            if (max !== null) { //replaces template tags with min, max and percent values in object
                row = tableRow.replace("{taxband}", "£" + min + " - " + "£" + max).replace("{percent}", (pct * 100) + "%");
            } else {
                row = tableRow.replace("{taxband}", "£" + min + "+").replace("{percent}", (pct * 100) + "%"); //used for last taxband
            } 

            if (taxablesum < 0) {
                row = row.replace("{taxable}", "£" + 0 + ".00").replace("{TAX}", "£" + 0 + ".00");
            }   else if (userInput > 1500000) {
                    row = row.replace("{taxable}", "£" + numberWithCommas(taxablesum)).replace("{TAX}", "£" + numberWithCommas(tax));
                    results.text("£" + numberWithCommas(tax));
                    effectiveRate.text(eRate + "%");
            }   else if (userInput > 925000) {
                    row = row.replace("{taxable}", "£" + numberWithCommas(taxablesum)).replace("{TAX}", "£" + numberWithCommas(tax));
                    results.text("£" + numberWithCommas(tax));
                    effectiveRate.text(eRate + "%");
            }   else if (userInput > 250000) {
                    row = row.replace("{taxable}", "£" + numberWithCommas(taxablesum)).replace("{TAX}", "£" + numberWithCommas(tax));
                    results.text("£" + numberWithCommas(tax));
                    effectiveRate.text(eRate + "%");
            }   else if (userInput > 125000) {
                    row = row.replace("{taxable}", "£" + numberWithCommas(taxablesum)).replace("{TAX}", "£" + numberWithCommas(tax));
                    results.text("£" + numberWithCommas(tax));
                    effectiveRate.text(eRate + "%");
            }   else {
                    row = row.replace("{taxable}", "£" + userInput).replace("{TAX}", "£" + numberWithCommas(tax));
                    results.text("£" + (numberWithCommas(tax) * 0));
                    effectiveRate.text(eRate * 0 + "%");
            }

            table.append(row);

            console.log(Number(tax) );
        }
         }

     }());
 });

EDIT 这是一个小提琴https://jsfiddle.net/p6c1w5r3/

某些按钮功能尚未完成,我希望首先正确计算

3 个答案:

答案 0 :(得分:0)

检查这个小提琴。 https://jsfiddle.net/p6c1w5r3/7/

基本上我们在循环外创建另一个名为totalTax的变量。然后在循环内部,我们将税值添加到此变量中。

最后,您不应每次都设置标签文本,而是在结尾处设置一次。

哦顺便说一句,当金额低于20000时,您的税收计算会返回奇怪的值。

答案 1 :(得分:0)

所以我找到了解决方案,在玩了一下之后,主要问题根源于taxablesum函数返回负数,这是用这段代码解决的

return Math.max(0, maxBand - min);

这是指向小提琴https://jsfiddle.net/nnyawjob/

的链接

感谢您指出我正确的方向

答案 2 :(得分:-1)

错误似乎是在你的税收计算功能中你收到一个负值(我没有深入研究它以检查为什么会这样)但你可以通过这个小辅助函数避免这种情况:{{1 }}

我已更新你的js小提琴,它现在似乎有效(至少显示一些税收价值)

Math.abs(x)

https://jsfiddle.net/p6c1w5r3/1/

修改

此更新包含total_tax的控制台日志(总计的税金) 希望这有帮助

https://jsfiddle.net/p6c1w5r3/4/