循环遍历对象数组,并按对象元素id返回每个总值的总和

时间:2014-03-10 18:27:16

标签: javascript jquery arrays loops object

计算税是一种非常复杂的发票方法。我不能解释整个过程,但如果你有问题,我会尽我所能回答。

我在JS中提出了一系列对象:

[
 {row_id: "20003859", expense_id: "429", tax_select: "tax1", tax_id: "1", tax_name: "GST 5%", tax_no: "", tax_value: "13.23"}, 
 {row_id: "20003859", expense_id: "429", tax_select: "tax2", tax_id: "3", tax_name: "QST 9.975%", tax_no: "", tax_value: "26.38"}, 
 {row_id: "20003840", expense_id: "409", tax_select: "tax1", tax_id: "1", tax_name: "GST 5%", tax_no: "", tax_value: "13.23"}, 
 {row_id: "20003840", expense_id: "409", tax_select: "tax2", tax_id: "3", tax_name: "QST 9.975%", tax_no: "", tax_value: "26.38"},
 {row_id: "20003870", expense_id: "419", tax_select: "tax1", tax_id: "2", tax_name: "HST 13%", tax_no: "", tax_value: "34.39"}
]

正如你所看到我有3个tax_ids:1,2和3.我可以有很多但是为了简单起见我只放了3个。

我需要 循环遍历此对象数组,并提出另一个对象数组 ,其中包含tax_id总计:

[
 {tax_name: "GST 5%", total_tax: sum of tax_value for tax_id = 1},
 {tax_name: "QST 9.975%", total_tax: sum of tax_value for tax_id = 3},
 {tax_name: "HST 13%", sum of tax_value for tax_id = 2}
]

之后,我可以遍历此数组并显示每个税的总计,添加小计并显示总发票。

另外,我应该按tax_select 对它们进行排序,但这是我可以忍受的事情。

我试过:其中selected_taxes是第一个对象数组

 for (i = 0; i < selected_taxes.length; i++){
        var sum = 0;
    $.each( selected_taxes[i], function( tax_id, tax_value ) {
        sum += tax_value;
    });
    console.log(sum);
 }

但没有运气。

非常感谢您的帮助或建议。

4 个答案:

答案 0 :(得分:1)

当您循环对象时,请查看它是什么,并为每个不同的taxId生成总和。

var sums = {}, obj, i;
for (i = 0; i < selected_taxes.length; i++){
    obj = selected_taxes[i];
    if (!sums[obj.tax_id]) {
        sums[obj.tax_id] = 0;
    }
    sums[obj.tax_id] += +obj.tax_value;
}
console.log(sums); //{ 1:26.46, 2:34.39, 3: 52.76}

http://jsfiddle.net/4X6Wb/

答案 1 :(得分:1)

我认为Array.prototype.reduce将是您最好的选择:

var totals = data.reduce(function(c,x){
    if(!c[x.tax_id]) c[x.tax_id] = {
        tax_name: x.tax_name,
        tax_id: x.tax_id, 
        total_tax: 0
    };
    c[x.tax_id].total_tax += Number(x.tax_value);
    return c;
}, {});

此方法生成一个对象,该对象具有税号ID作为其属性。如果你真的想要一个平面数组,你可以在事后将其转换为数组:

var totalsArray = [];
for(var taxId in totals){
    totalsArray.push(totals[taxId]):
}

示范:http://jsfiddle.net/3jaJC/1/

答案 2 :(得分:1)

使用reduce方法:

selected_taxes.reduce(function (p, c) {
    if (p[c["tax_id"]]) {
        p[c["tax_id"]]["total_tax"] += +c["tax_value"];
    } else {
        p[c["tax_id"]] = {
            "tax_name": c["tax_name"],
            "total_tax": +c["tax_value"]
        }
    }
    return p;
}, {});

这将返回一个包含所需数据的新对象:

{
    "1": {
        "tax_name": "GST 5%",
        "total_tax": 26.46
    },
    "2": {
        "tax_name": "HST 13%",
        "total_tax": 34.39
    },
    "3": {
        "tax_name": "QST 9.975%",
        "total_tax": 52.76
    }
}

DEMO

答案 3 :(得分:0)

我使用类型化数组的解决方案:

var sum_arr = new Float32Array(arr.length); for (var i = 0; i < arr.length; i++){ var tax_id = arr[i].tax_id; sum_arr[tax_id] += parseFloat(arr[i].tax_value); }

jsfidle:  http://jsfiddle.net/LJ7Nd/

这个想法:假设你有n个tax_ids。创建一个名为sum_arr的长度为n的数组。在每次迭代时拉出tax_id,并使用相应的tax_value递增数组中的特定插槽。那么当你想要tax_id = 1的所有tax_values的总和时,你只需索引sum_arr [1]。