I am working on a web-page for my company about an on-line survey page, our customer service team will simply input some check-box questions into a database. and my job is to display them on a page and gather the player's answers back to our database.
for example if I have 12 questions in the database, and I need it to be displayed in a table as:
1 5 9
2 6 10
3 7 11
4 8 12
or, if I have 13 questions, it should be displayed as
1 6 10
2 7 11
3 8 12
4 9 13
5
this can be done with some if else in PHP, but i would like to do it in mathematical ways just to enrich my knowledge.
any suggestion or hints are appreciate if I can pass the total questions(in this case 13) and vertical column counts(in this case 3) in a formula, and it simply return the orders of the numbers in this way {1, 6, 10, 2, 7, 11, 3, 8, 12, 4, 9, 13, 5}
honestly, I will not rewrite the survey page. I am just curious if this can be done with some math without if/else in the programming.
EDIT:
Here's my latest solution for generating the array which is even more mathematical than before:
$q = 27;//number of questions
$c = 4;//number of columns
$m = $q%$c;//modulus
$step = floor($q/$c);
$arr = array();
for ($n=0; $n<$q; $n++){
$arr[] = 1 + $step*($n%$c) + ($m + $n%$c - abs($m - $n%$c))/2 + floor($n/$c);
}
The output is as follows:
array(1, 8, 15, 22, 2, 9, 16, 23, 3, 10, 17, 24, 4, 11, 18, 25, 5, 12, 19, 26, 6, 13, 20, 27, 7, 14, 21);
ORIGINAL ANSWER:
$q = 13;//number of questions
$c = 3;//number of columns
$mod = array_fill(0, $c, 0);
for ($i=0; $i<($q%$c); $i++){
$mod[$i] = 1;
}
$step = floor($q/$c);
$arr = array();
$cum = 0;
for ($i=0; $i<$c; $i++){
$cum += @$mod[$i-1];
$arr[] = 1 + $step*$i + $cum;
}
$next = $arr;
for ($i=1; $i<$step; $i++){
foreach ($next as $key => $value){
$next[$key]++;
}
$arr = array_merge($arr, $next);
}
for ($i=0; $i<$c; $i++){
$next[$i] = ($next[$i] + 1)*$mod[$i] ;
}
$arr = array_filter(array_merge($arr, $next));
var_dump($arr);
The output is:
array(1, 6, 10, 2, 7, 11, 3, 8, 12, 4, 9, 13, 5);
Here's my solution for generating a table:
$q = 27;//number of questions
$c = 4;//number of columns
$cell = '<td>i</td>';
$table = '<table>';
$mod = array_fill(0, $c, 0);
for ($i=0; $i<($q%$c); $i++){
$mod[$i] = 1;
}
$step = floor($q/$c);
$arr = array();
$cum = 0;
$table .= '<tr>';
for ($i=0; $i<$c; $i++){
$cum += @$mod[$i-1];
$num = 1 + $step*$i + $cum;
$arr[] = $num;
$table .= str_replace('i', $num, $cell);
}
$table .= '</tr><tr>';
$next = $arr;
for ($i=1; $i<$step; $i++){
foreach ($next as $key => $value){
$num = ++$next[$key];
$table .= str_replace('i', $num, $cell);
}
//$arr = array_merge($arr, $next);
$table .= '</tr><tr>';
}
$table = substr($table, 0 , -4);
for ($i=0; $i<$c; $i++){
$next[$i] = ($next[$i] + 1)*$mod[$i] ;
}
$next = array_filter($next);
$span = $c - count($next);
$ini = '';
$fin = '';
$last = '';
foreach ($next as $key => $value){
$ini = '<tr>';
$last .= str_replace('i', $value, $cell);
$fin = '<td span="'.$span.'"> </td></tr>';
}
//$arr = array_merge($arr, $next);
$table .= $ini.$last.$fin.'</table>';
echo $table;
With 27 questions and 4 columns, the output is:
<table>
<tr><td>1</td><td>8</td><td>15</td><td>22</td></tr>
<tr><td>2</td><td>9</td><td>16</td><td>23</td></tr>
<tr><td>3</td><td>10</td><td>17</td><td>24</td></tr>
<tr><td>4</td><td>11</td><td>18</td><td>25</td></tr>
<tr><td>5</td><td>12</td><td>19</td><td>26</td></tr>
<tr><td>6</td><td>13</td><td>20</td><td>27</td></tr>
<tr><td>7</td><td>14</td><td>21</td><td span="1"> </td></tr>
</table>
You can, of course, modify the value of $cell
to insert a link or whatever you want into the table cells.
You can try this by using mod function i.e. '%' and also use array in it. I have a question here. Will the number of column remain 3 ? If so then you can take 3 different array to store the records in order. Then display those in each column. Yes, here you cannot do this by using a single html table, you need to use div for each column.
Assuming your checkboxes are stored in an array called $target
.
<?php
$target = array(1,2,3,4,5,6,7,8,9,10,11,12,13);
$target = array_chunk($target, 3); //Split the array into chunks of 3.
$result = array_map(function ($el) {
return implode("</td><td>", $el); //Implode the inner arrays with table cells
}, $target);
$result = implode("</td></tr><tr><td>", $result); //Implode the outer arrays with table rows.
echo "<table><tr><td>";
echo $result;
echo "</td></tr></table>";
You'll get a table in groups of three.
If you want a function that will determine the number of columns, you just change the number "3" in array_chunk
to the argument of that function :)
The below gives the result in the first case as an array. But when all the cells of the matrix do not have value i think one have to use if else statement
<?php
function lists ($total_cells, $vertical_cols) {
$total = $total_cells;
$cols = $vertical_cols;
$hor = (int)($total/$cols);
$res = array();
$j=0;
$current = 1;
for($j=1;$j<=$hor;$j++){
$current = $j;
for($i = 1; $i<=$cols; $i++) {
$res[$j][] = $current;
$current = $current+$hor;
}
}
return $res;
}
?>