I've just begun learning php and this is my first time encountering associative arrays. I'm trying to echo a specific value from the innermost array but failing to do so.
This is my array -
define('TAX_RATES', array(
'Single' => array(
'Rates' => array(10,12,22,24,32,35,37),
'Ranges' => array(0,9700,39475,84200,160725,204100,510300),
'MinTax' => array(0, 970,4543,14382,32748,46628,153798)
),
'Married_Jointly' => array(
'Rates' => array(10,12,22,24,32,35,37),
'Ranges' => array(0,19400,78950,168400,321450,408200,612350),
'MinTax' => array(0, 1940,9086,28765,65497,93257,164709)
),
'Married_Separately' => array(
'Rates' => array(10,12,22,24,32,35,37),
'Ranges' => array(0,9700,39475,84200,160725,204100,306175),
'MinTax' => array(0, 970,4543,14382.50,32748.50,46628.50,82354.75)
),
'Head_Household' => array(
'Rates' => array(10,12,22,24,32,35,37),
'Ranges' => array(0,13850,52850,84200,160700,204100,510300),
'MinTax' => array(0, 1385,6065,12962,31322,45210,152380)
)
)
);
I have to run a foreach loop to loop through the 'Single', 'Married_Jointly' etc. statuses to output the first row and then a for loop to output the rest of the rows. The output should look like:
Single
Taxable Income Tax Rate
$0 - $9700 10%
$9701 - $39475 $970 12%
.....
Married_Jointly
Taxable Income Tax Rate
$0 - $19400 10%
$19401 - $78950 $1940 12%
.....
Code I've tried so far:
$keys = array_keys(TAX_RATES);
for($i = 0; $i < count(TAX_RATES); $i ){
echo $keys[$i] . "<br>";
echo "<table>";
echo "<tr>";
echo "<th> Taxable Income </th>";
echo "<th> Tax Rate </th>";
echo "</tr>";
foreach(TAX_RATES[$keys[$i]] as $key => $value){
echo "<tr>";
echo "<td> $0 - $value[1] </td>";
echo "<td> $value[0]% </td>";
echo "</table> <br>";
}
}
This is the result I'm getting -
Single
Taxable Income Tax Rate
$0 - $12 10%
$0 - $9700 0%
....
Married_Jointly
Taxable Income Tax Rate
$0 - $12 10%
$0 - $19400 0%
.....
I'm having a tough time iterating over a complex associative array like this, any help would be appreciated.
CodePudding user response:
<?php
// Loop through the different groupings, Single, Married_Jointly, etc.
foreach(TAX_RATES as $group => $info) {
echo $group . "<br>";
echo "<table>";
echo "<tr>";
echo "<th> Taxable Income </th>";
echo "<th> Tax Rate </th>";
echo "</tr>";
// Loop through the rates.
foreach ($info['Rates'] as $key => $value){
// Get the lower bound of the range.
$range_lower_bound = $info['Ranges'][$key];
// If the lower bound range is not the first range,
// then increment by 1, since the original value is
// already used as the upper bound of the previous
// range.
if ($key !== 0) {
$range_lower_bound = 1;
}
// Get the upper bound, which is the next item
// along. Check that it exists; it won't if we are
// on the last item.
$range_upper_bound = $info['Ranges'][$key 1] ?? NULL;
// Produce the range text that we will print.
$range_text = '$' . $range_lower_bound;
// If an upper bound exists, print it, otherwise
// just print ' '.
$range_text .= $range_upper_bound
? ' - $' . $range_upper_bound
: ' ';
$rate = $value . '%';
// The minimum tax.
$minimum_tax = $info['MinTax'][$key];
// Prefix the rate percent with the minimum tax if
// the minimum tax is more than 0.
if ($minimum_tax > 0) {
$rate = '$' . $minimum_tax . ' ' . $rate;
}
echo "<tr>";
echo "<td>" . $range_text . "</td>";
echo "<td>" . $rate . "</td>";
echo "</tr>";
}
echo "</table>";
}
CodePudding user response:
I recommend breaking up your table generating into its repeatable parts.
Create template strings and fill them with data as you iterate -- this will make maintaining your application layout much simpler.
Code: (Demo -- click the eye icon to see the rendered html)
$tableTemplate = <<<TABLE
<h2>%s</h2>
<table border="1">
<tr>
<th>Taxable Income</th>
<th>Tax Rate</th>
</tr>
%s
</table>
TABLE;
$rowTemplate = <<<ROW
<tr>
<td>%d - %d</td>
<td>%d%%</td>
</tr>
ROW;
foreach (TAX_RATES as $status => $data) {
$rows = [];
foreach ($data['Rates'] as $i => $rates) {
$lastRange = !$i ? 0 : $data['Ranges'][$i - 1] 1;
$rows[] = sprintf($rowTemplate, $lastRange, $data['Ranges'][$i], $rates);
}
printf($tableTemplate, $status, implode("\n", $rows));
}
Notice that a literal %
in the template strings must be "escaped" by another %
. Otherwise, mark variable strings as %s
, variable integers as %d
, and floats as %f
. This is a basic rundown, but there are more formatting features that you can enjoy with the printf()
family of functions. (sprintf()
is the "silent" version of printf()
that just returns its payload instead of printing it.)