I want to merge the table row if the date have an same id's. I have some array data like this :
Array
(
[0] => Array
(
[id] => 2
[date] => 05/13/2014
[content] => some contents 1
[act] => act1 act2 act3
)
[1] => Array
(
[id] => 2
[date] => 05/28/2014
[content] => some contents 1
[act] => act1 act2 act3
)
[2] => Array
(
[id] => 7
[date] => 06/04/2014
[content] => some contents 2
[act] => act1 act2 act3
)
)
Then I tried to group its data into the same id by :
if($queryx = $this->mymodel->myfunction($par)){
$datax = $queryx;
}
$i = 0;
foreach ($datax as $idx => $val) {
$dates[$val['id']][$i] = $val['date'].",".$val['id'];
$contn[$val['id']][$i] = $val['content'];
$i++;
}
then :
$j = 0; $y = 0;
echo "<table border='1'>
";
foreach ($dates as $idx => $val) {
$tmpexp = explode(',', $val[$j]);
echo "<tr>
";
echo "<td rowspan='".count($val)."'>".$tmpexp[0]."</td>
";
foreach ($val as $idx1 => $val1) {
if($idx1 > 0)
{
echo "<tr>
";
}
echo "<td>".$dates[$tmpexp[1]][$y]."</td>
";
if($idx1 < 1)
{
echo "<td rowspan='".count($val)."'>".$contn[$tmpexp[1]][$y]."</td>
";
echo "<td rowspan='".count($val)."'>act1 act2 act3</td>";
echo "</tr>
";
}
$y++;
}
$j++;
}
echo "</table>";
There is no problem if the data have at least two child, but if the date only have one child (see data with id's 7) there is show an error because Undefined offset. So how I add some handler if there is only one child on the data. There is my desired result:
Please see this image:
I use the 'read ahead' technique for processing nested loops. It does mean that 'foreach' loops cannot be used as the next record must be read as soon as the current one has been processed. Basically, the last action you do in the loop is read the next record as you are setting it up for the next iteration. Note, you never test when to print a record as that is decided by the structure of the groups. The code loops are the same as the structure of the groups in the data
A 'group' is all the records with the same id.
I assume that the 'content' and 'act' are identical for each entry in the group.
Edited to add 'rowspan' attributes to the appropriate 'td' tags. I suspect css may be easier at this point.
The issue is that the group cannot be displayed until it is known how many entries are in it.
So, i 'buffer' all the records belonging to a group in an array. at the end of the group, it is displayed with the appropriate 'rowspan' attributes in the html.
It is tested on PHP 5.3.18. It includes test data.
<?php /* Q24028866 */
$testData = array(array('id' => 2, 'date' => '05/13/2014', 'content' => 'some contents 2', 'act' => 'act1 act2 act3'),
array('id' => 2, 'date' => '05/28/2014', 'content' => 'some contents 2', 'act' => 'act1 act2 act3'),
array('id' => 7, 'date' => '06/04/2014', 'content' => 'some contents 7', 'act' => 'act1 act2 act3'),
array('id' => 8, 'date' => '06/08/2014', 'content' => 'some contents 8', 'act' => 'act1 act2 act3'),
array('id' => 8, 'date' => '06/09/2014', 'content' => 'some contents 8', 'act' => 'act1 act2 act3'));
?>
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<table border='1'>
<thead><th>Date</th><th>Content</th><th>Act</th></thead>
<?php
// use 'read ahead' so there is always a 'previous' record to compare against...
$iterContents = new \ArrayIterator($testData);
$curEntry = $iterContents->current();
while ($iterContents->valid()) { // there are entries to process
$curId = $curEntry['id'];
// buffer the group to find out how many entries it has...
$buffer = array();
$buffer[] = $curEntry;
$iterContents->next(); // next entry - may be same or different id...
$curEntry = $iterContents->current();
while ($iterContents->valid() && $curEntry['id'] == $curId) { // process the group...
$buffer[] = $curEntry; // store all records for a group in the buffer
$iterContents->next(); // next entry - may be same or different id...
$curEntry = $iterContents->current();
}
// display the current group in the buffer...
echo '<tr>';
echo '<td>', $buffer[0]['date'], '</td>';
$rowspan = count($buffer) > 1 ? ' rowspan="'. count($buffer) .'"' : '';
echo '<td', $rowspan, '>', $buffer[0]['content'], '</td>',
'<td', $rowspan, '>', $buffer[0]['act'], '</td>';
echo '</tr>';
for($i = 1; $i < count($buffer); $i++) {
echo '<tr><td>', $buffer[$i]['date'], '</td>';
echo '</tr>';
}
} ?>
</table>
</body>
</html>
The following code will give you a clue what you should do,
$newArray = array();
$counter=0;
foreach($datax as $key=>$val){
$newArray[$val['id']][$counter]['date'] = $val['date'];
$newArray[$val['id']][$counter]['content'] = $val['content'];
$newArray[$val['id']][$counter]['act'] = $val['act'];
$counter++;
}
$newArray = array_map('array_values', $newArray);