如何使用简洁的片段确定分层税率? [关闭]

I am trying to create a tiered tax calculator.

The user enters an amount, say 500,000

From that amount, I then have the following tiers that tax is charged as follows:

        0 -   125,000 = 0%
  125,001 -   250,000 = 2%
  250,001 -   925,000 = 5%
  925,001 - 1,500,000 = 10%
1,500,001 -   or more = 12%

So no tax on the first 125,000, then 2% on the next 124,999 and so on.

I can come up with long winded calculations with far too many lines of code. I am sure there is a relatively simple way to do this, so I am bowing to the greater knowledge of folks here to find a more concise method.

Hm, nice challenge though. I'm sorry, I couldn't really come up with a smart way, but if you are in dire need I created this little function;

function calculator($value) {

    if(!is_int($value) && !is_double($value))
        return;

    if($value > 1500000)
        $value = $value - ($value*0.12);

    elseif($value > 925000)
        $value = $value - ($value*0.10);

    elseif($value > 250000)
        $value = $value - ($value*0.05);

    elseif($value > 125000)
        $value = $value - ($value*0.02);

    return $value;

}

You just feed it with a value (int or double) and it will return the calculated value. Be aware you can't use , (comma) though.

Edit: Changed to logic a little.

This won't do any number validation or currency formatting, but it does condense the snippet fairly well. I am also not sure which figure you wanted as a result, so I am returning three values: the rate, the amount of tax, and the price less the tax.

Rather than a block of if/else statements, I've elected to use array functions. (Demo)

Method #1: 2-lines and a return

function tax($value) {
    $tiers=['.12'=>1500000,'.1'=>925000,'.05'=>250000,'.02'=>125000,'0'=>0];
    $rate=key(array_filter($tiers,function($threshold)use($value){return $value>$threshold;}));
    return [$rate,$value*$rate,$value-$value*$rate];
}

Method #2: 4-lines and a return, but more efficient

function tax($value) {
    $tiers=['.12'=>1500000,'.1'=>925000,'.05'=>250000,'.02'=>125000,'0'=>0];
    foreach($tiers as $rate=>$threshold){
        if($value>$threshold){break;}  // $rate will be preserved outside of the loop
    }
    return [$rate,$value*$rate,$value-$value*$rate];
}

Calling the function like this: var_export(tax(126999)); will output:

array (
  0 => '.12',
  1 => 1523988.0,
  2 => 11175912.0,
)

Since you are placing "code brevity" ahead of "code efficiency", I would recommend Method #1. Because this task is so small/light, I don't think anyone will notice any gains via micro-optimization.

p.s. If you are not doing this multiple times in the same script and/or don't want a function call, you can declare $rate just by using this:

$tiers=['.12'=>1500000,'.1'=>925000,'.05'=>250000,'.02'=>125000,'0'=>0];
$rate=key(array_filter($tiers,function($threshold)use($value){return $value>$threshold;}));

or

$tiers=['.12'=>1500000,'.1'=>925000,'.05'=>250000,'.02'=>125000,'0'=>0];
foreach($tiers as $rate=>$threshold){
    if($value>$threshold){break;}
}