0

I'm in the process of teaching myself javascript and it looks at though I've hit a road block. As an exercise I am trying to build a tax calculator.

Here is an object I built that contains the tax brackets:

var taxBracket = [
{bracket: 1, from:0, to:18200, percentage :0, amount:0},
{bracket: 2, from:18201, to:37000, percentage :19, over:18200, amount:0},
{bracket: 3, from:37001, to:80000, percentage :32.5, over:37000, amount:3752},
{bracket: 4, from:80001, to:180000, percentage :37, over:80000, amount:17547},
{bracket: 5, from:180001, to:0, percentage :45, over:180000, amount:54547}];

and here is the function that loops through object to find the corresponding tax bracket of y

function returnTax (y){
    for(var x in taxBracket){
    if (y >= taxBracket[x].from && y <= taxBracket[x].to){
        var z = taxBracket[x].amount + ((grossIncome-taxBracket[x].over) * (taxBracket[x].percentage/100));
        return z;   
    }
};

The issue is that if y is over 180000, it errors out as to is 0. Is this only solution to this an else statement repeating the functions of the if statement? Thank for your help!

therealrootuser
  • 10,215
  • 7
  • 31
  • 46
andrew_b
  • 29
  • 1
  • 4
  • 1
    Do not use `for ... in` for arrays. – Ram Aug 31 '14 at 02:52
  • You could make "to" some very large number. – Code-Apprentice Aug 31 '14 at 03:12
  • Unrelated to the problem you asked about, your function uses a `grossIncome` variable that isn't declared in the function. Shouldn't that be `y`? Also, I'd suggest renaming the `y` variable to something more meaningful, like `income` or `grossIncome`. Finally, if you're testing values entered by the user, be careful to ensure they enter an integer (or that you round for them), otherwise if they enter, say, 37000.5 they will have a tax bill of 0. – nnnnnn Aug 31 '14 at 04:29
  • Is there a way to deal with both floats and integers? – andrew_b Aug 31 '14 at 07:04

4 Answers4

3

Good job with it so far. Simply using Infinity instead of defaulting to 0 on the final bracket will fix it. I've made a couple of recommendations on your syntax as well, hope it helps.

var taxBracket = [
    {bracket: 1, from: 0, to: 18200, percentage: 0, amount: 0},
    {bracket: 2, from: 18201, to: 37000, percentage: 19, over: 18200, amount: 0},
    {bracket: 3, from: 37001, to: 80000, percentage: 32.5, over: 37000, amount: 3752},
    {bracket: 4, from: 80001, to: 180000, percentage: 37, over: 80000, amount: 17547},

    // Use Infinity instead of 0 for the "to" value of bracket 5
    {bracket: 5, from: 180001, to: Infinity, percentage: 45, over: 180000, amount: 54547}
];

// Variable names like 'x', 'y' and 'z' can cause problems with code readability.
// Descriptive names such as "income", or even "string" or "int" will help you out when you come to review your code later!
function returnTax(y){

    // Using for..in with arrays can cause issues with enumerating over object properties.
    // You don't have to worry about it in this case, but a standard for loop (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for) is better practice.
    for(var x = 0; x < taxBracket.length; x++){

        if(y <= taxBracket[x].to){

            // I find breaking up long calculations into separate variables can make it
            // more readable. More preference than anything else though!
            var amountOver = grossIncome - taxBracket[x].over;
            var percent = taxBracket[x].percentage / 100;
            return taxBracket[x].amount + (amountOver * percent);

        }

    }

}
Richard Foster
  • 608
  • 3
  • 6
  • Note that (assuming contiguous tax brackets) you can simplify the `if` statement because you don't need the `.from` test: `if(y <= taxBracket[x].to){`. – nnnnnn Aug 31 '14 at 04:23
2

You are creating an array literal of object literals. You should loop through arrays with a standard for loop.

Antiga
  • 2,264
  • 1
  • 20
  • 28
  • 1
    [This is a good suggestion, in general](http://stackoverflow.com/questions/500504/why-is-using-for-in-with-array-iteration-such-a-bad-idea), but doesn't really answer this question. Using a regular `for` loop instead would have no affect on `y <= taxBracket[x].to` being `false` when the `to` is `0`. – Jonathan Lonowski Aug 31 '14 at 03:21
1

One solution is to make the last "to" field some very large number.

Code-Apprentice
  • 81,660
  • 23
  • 145
  • 268
  • I had thought of that, but it doesn't really deal with the problem. It looks like infinity is the fix. Thanks – andrew_b Aug 31 '14 at 06:13
0

you can use built in function to loop array of object like

yourArray.forEach
( function (arrayItem)
{
var x =
arrayItem.prop1 + 2;
alert(x);
 });
Anonymous
  • 11,748
  • 6
  • 35
  • 57
A l w a y s S u n n y
  • 36,497
  • 8
  • 60
  • 103