【问题标题】:Loop through array of objects and return sum of each total values by object element id遍历对象数组并按对象元素 id 返回每个总值的总和
【发布时间】:2014-04-14 00:53:39
【问题描述】:

我正在计算税金,这是一种非常复杂的开票方式。我无法解释整个过程,但如果您有问题,我会尽我所能回答。

我在 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_id: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);
 }

但没有运气。

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

【问题讨论】:

  • 我认为您不需要嵌套循环。
  • 同意,但是我怎样才能通过 tax_id 获得只有第一个对象数组的总数?
  • 当您在对象上循环时,查看它是什么 taxId 并为每个不同的 taxId 生成一个总和。
  • 谢谢大家!我喜欢 Stackoverflow!爱它!我现在在做什么?我有 4 个答案,都是有效答案!
  • 祝你编码顺利。如果您还有什么需要帮助的,请告诉我们。

标签: javascript jquery arrays loops object


【解决方案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;
}, {});

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

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

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

【讨论】:

  • 我正在使用这个解决方案。谢谢!
【解决方案2】:

当您遍历对象时,查看它是什么 taxId 并为每个不同的 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/

【讨论】:

  • 非常感谢您的意见!
【解决方案3】:

使用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

【讨论】:

    【解决方案4】:

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

    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); }

    jsfile: http://jsfiddle.net/LJ7Nd/

    想法:假设您有 n 个 tax_id。创建一个名为 sum_arr 的长度为 n 的数组。在每次迭代时拉出 tax_id,并将数组中的特定槽增加相应的 tax_value。然后,当您想要 tax_id = 1 的所有 tax_values 的总和时,您只需索引 sum_arr[1]。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-07-21
      • 2016-10-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-19
      • 2022-06-16
      • 1970-01-01
      相关资源
      最近更新 更多