Dynamic table dynamic table results vertically not horizontally

I have an array of data that I want to display in a dynamic table, but need it vertically.

I am currently getting the following output:

Example 1:

1 - 2 - 3 - 4
5 - 6 - 7 - 8
9 - ... etc.

      

But I need it like this:

Example 2:

1 - 4 - 7
2 - 5 - 8
3 - 6 - 9

      

I've googled and stacked, but can't find a straightforward answer that I can use to solve my problem.

$array = array("4|Four","12|Twelve","2|Two","5|Five","11|Eleven","3|Three","1|One","6|Six","10|Ten","8|Eight","7|Seven","9|Nine");

$maxcols = 3;
$i = 0;

$table = "<table width=\"80%\" border=\"0\">\n";
$table .= "<tr>\n";


if(!empty($array))
{
rsort($array,SORT_NUMERIC);
for($p=0;$p<sizeof($array);$p++)
{
list($num,$title) = explode("|", trim($array[$p]));


if ($i == $maxcols) 
{
$i = 0;
$table .= "</tr>\n<tr>\n";
}
$table .= "<td>"."[ ".$num." ]"." ".$title."</td>\n";
$i++;
}

while ($i < $maxcols) 
{
$table .= "<td>&nbsp;</td>\n";
$i++;
}

$table .= "</tr>\n";
$table .= "</table>\n";
}

echo $table;

      

This code above outputs as shown in the first example, but I can't get my head to get it to output as shown in the second example.

+3


source to share


3 answers


I originally thought about using array_chunk to split an array into strings, but then it occurred to me that it could be done in the same way as with math.

$rows = 3; // define how many rows as you want

$array = array("4|Four","12|Twelve","2|Two","5|Five","11|Eleven","3|Three","1|One",
    "6|Six","10|Ten","8|Eight","7|Seven","9|Nine");
rsort($array,SORT_NUMERIC);

// determine number of columns needed to fit the values into the number of rows you want
$columns = count($array) / $rows; 

$table = '<table width="80%" border="0">';
for ($i=0; $i < $rows; $i++) { 
    $table .= '<tr>';
    for ($j=0; $j < $columns; $j++) {
        $index = (int) ($j * $rows + $i); // Do the math to get the proper array index
        if (isset($array[$index])) {                    
            list($num,$title) = explode("|", trim($array[$index]));
            $table .= "<td>"."[ ".$num." ]"." ".$title."</td>\n";
        } else {
            $table .= '<td>&nbsp;</td>';
        }
    }
    $table .= '</tr>';
}
$table .= '</table>';

      

The above example creates a grid like this where the numbers are the keys of the array.

0  3  6  9
1  4  7  10
2  5  8  11

      

The math that creates this two-loop grid looks like this:



0*3+0  1*3+0  2*3+0  3*3+0
0*3+1  1*3+1  2*3+1  3*3+1
0*3+2  1*3+2  2*3+2  3*3+2

      

or in words (column index * total number of rows) + row index. The nested part of the loop will remain unchanged whether you need to specify the number of rows or the number of columns. The only thing to change is the math at the beginning to calculate how many rows are needed for a specified number of columns, or vice versa. If you change the start part to

$columns = 3; 
$rows = ceil(count($array) / $columns);

      

Then you can specify the number of columns, not the number of rows. ceil

is necessary because any remainder of the division must be rounded to get the total number of lines needed. I think this is why you were getting duplicate values ​​when you first switch rows and columns.

+3


source


This is how I did it.

    <table align="center" style="width:40%;">
<tr>
<th>Column 1</th>
<th>Column 2</th>
<th>Column 3</th>
</tr>
<?
$rotate = 0;
$amount = 1;
while($amount <= 50)
{
if($rotate == 0) {
echo '<tr>
<td>test</td>';
$rotate = 1;
}
else if($rotate == 1) {
echo '<td>test2</td>';
$rotate = 2;
}
else if($rotate == 2) {
echo '<td>test3</td>';
$rotate = 0;
echo '</tr>';
}

$amount++;

}
echo '</tr></table>';

      



This will work in a blank php page so you can see how it works.

0


source


To expand further on @ DontPanic's answer, the problem of translating array keys can be abstracted in such a way that you can have any number of columns. Both versions of math are mostly equivalent.

// returns a closure that can be used to translate the index order

function getIndexTranslator($list, $numColumns) {
    $numRows = ceil(count($list)/$numColumns);
    return function($x) use ($list, $numColumns, $numRows){
        return ($x % $numColumns) * $numRows + floor($x / $numColumns);
    };
}

      

Then you can use the return function so that you can move the elements in the document order you want. This is how you would use the above function.

$transformer = getIndexTranslator($arr, 3);

for($x = 0; $x < count($arr); $x++){
    echo $arr[$transformer($x)], $x % 3 == 2?"\n":" ";
}

      

Play with it yourself here

0


source







All Articles