Display table values ​​vertically while maintaining table structure

Other methods were tested, used to arrange the array values vertically for use in the table, but most of them were equivalent to flipping your table 90 degrees to the right. I tried to figure out how to implement this correctly, but I think I need help.

For example, a table (horizontal order):

abcde fghij klmno pqr 

Reordered to (vertical order):

 aeimp bfjnq cgkor dhl 

As you can see, the structure is preserved since the last two cells are empty.

Not this way:

 aeimq bfjnr cgko dhlp 

In this example, the table is akin to turning it sideways. Does anyone know how to do this correctly?

+6
source share
3 answers

EDITED: It's harder than I thought, and I messed it up for the first time (or two). Now it should work.

Let's say you have a table structure stored in a two-dimensional array:

 $data = array( array('a', 'b', 'c', 'd', 'e'), array('f', 'g', 'h', 'i', 'j'), array('k', 'l', 'm', 'n', 'o'), array('p', 'q', 'r') ); 

Since you want to keep the same “shape”, you need to determine the size of the table. To do this, we can take the count first row, since we know that the first row should be the maximum width of the table. Height is simply the number of elements in the array.

 $width = count($data[0]); // 5 $height = count($data); // 4 

We also need the total number of elements, but we can overestimate it by taking $ width * $ height.

 $total = $width * $height; // 20 

Then it's really just math to figure out where everything goes. We must use a separate counter for old and new indexes, because we will have to increase them differently as soon as we start to have holes.

 $new_data = array(); $j = 0; for($i = 0; $i < $total; $i++) { $old_x = floor($i / $width); // integer division $old_y = $i % $width; // modulo do { $new_x = $j % $height; // modulo $new_y = floor($j / $height); // integer division $j++; // move on to the next position if we have reached an index that isn't available in the old data structure } while (!isset($data[$new_x][$new_y]) && $j < $total); if (!isset($new_data[$new_x])) { $new_data[$new_x] = array(); } if (isset($data[$old_x][$old_y])) { $new_data[$new_x][$new_y] = $data[$old_x][$old_y]; } } 
+2
source

The trick is to subtract it for the “hanging” columns. These are columns that do not have a value in the last row.

 // setup some initial test data... rip this out and replace with whatever $values = array(); for ($x = 0; $x < 18; ++$x) $values[] = chr($x + ord("a")); 

We can arbitrarily change the number of columns. The number of rows is determined by the size of our data divided by the number of columns used.

 // change # of columns to desired value $columns = 5; $rows = (int) ceil(count($values) / $columns); 

Some columns freeze. That is, the column does not have a value in the last row.

 // the number of columns that will "hang" or miss a value in the last row $hanging_columns = $columns * $rows - count($values); $counter = 0; for ($y = 0; $y < $rows; ++$y) { for ($x = 0; $x < $columns; ++$x) { // if we've displayed all values, stop if ($counter++ >= count($values)) break; // calculate the correct index to display $index = ($y + $x * $rows); // if we are in a hanging column, we need to back up by one if ($x > $columns - $hanging_columns) $index -= 1; // display the value echo $values[$index] . " "; } echo "\n"; } 
+1
source

Here is another solution

 $unflipped = array('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n'); function flip90($arr, $lineHeight) { $tbl = array(); $index = 0; $counter = 1; for($i = 0; $i < count($arr); $i++) { if($counter > $lineHeight) { $index++; $counter = 1; } if($counter <= $lineHeight) { $tbl[$index][$counter] = $arr[$i]; $counter++; } } return $tbl; } $flipped = flip90($unflipped, 5); echo "<pre>"; var_dump($flipped); echo "<pre>"; 

The function needs an array and row height to determine the size of the table

0
source

Source: https://habr.com/ru/post/950037/


All Articles