admin管理员组

文章数量:1357712

I'm calculating taxes for a very plicate invoicing approach. I can't explain the whole process but if you have questions I will answer as best as I can.

I e up with an array of objects in 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"}
]

As you can see I have 3 tax_ids: 1, 2 and 3. I can have many but for the sake of simplicity I put only 3.

I need to loop through this array of objects and e up with another array of objects having the totals by 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}
]

After that I can loop through this array and display the totals of each tax, adding subtotal and display the total invoice.

Also, I should sort them by tax_select but this it's a thing I can live with.

I have tried to: where selected_taxes is the first array of objects

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

but no luck.

Many thanks for your help or suggestions.

I'm calculating taxes for a very plicate invoicing approach. I can't explain the whole process but if you have questions I will answer as best as I can.

I e up with an array of objects in 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"}
]

As you can see I have 3 tax_ids: 1, 2 and 3. I can have many but for the sake of simplicity I put only 3.

I need to loop through this array of objects and e up with another array of objects having the totals by 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}
]

After that I can loop through this array and display the totals of each tax, adding subtotal and display the total invoice.

Also, I should sort them by tax_select but this it's a thing I can live with.

I have tried to: where selected_taxes is the first array of objects

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

but no luck.

Many thanks for your help or suggestions.

Share Improve this question asked Mar 10, 2014 at 18:27 Adrian P.Adrian P. 5,2282 gold badges49 silver badges49 bronze badges 5
  • 3 I don't think you need a nested loop. – Kevin B Commented Mar 10, 2014 at 18:32
  • Agree but how can I have the totals by tax_id having only the first array of objects? – Adrian P. Commented Mar 10, 2014 at 18:35
  • 1 When you're looping over the objects, see what taxId it is and generate a sum for each different taxId. – Kevin B Commented Mar 10, 2014 at 18:35
  • 1 Thanks all! I love Stackoverflow! Love it! What I'm doing now? I have 4 answers, all valid answers! – Adrian P. Commented Mar 10, 2014 at 19:00
  • Good luck with coding. Give us a shout if there's anything else you need help with. – monika Commented Mar 10, 2014 at 19:20
Add a ment  | 

4 Answers 4

Reset to default 7

I think Array.prototype.reduce will be your best bet for this:

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

This approach generates an object that has, as its properties, the tax ID numbers. If you really want a flat array from that, you can convert that into an array after the fact:

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

Demonstration: http://jsfiddle/3jaJC/1/

When you're looping over the objects, see what taxId it is and generate a sum for each different 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/4X6Wb/

Use the reduce method:

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

This returns a new object containing the desired data:

{
    "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

My solution using typed arrays:

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/LJ7Nd/

The idea: assume you have n tax_ids. Create an array of length n called sum_arr. Pull the tax_id at each iteration and increment that particular slot in the array by the corresponding tax_value. Then when you want the sum of all tax_values of tax_id = 1 you simply index sum_arr[1].

本文标签: