I have following array of record which contains user as well as location information:
$arr =
[
[
'user_id' => 5,
'l_id' => 10,
'Name' => 'John Doe',
'Location' => 'Chicago',
'date' => '2021-10-02'
],
[
'user_id' => 5,
'l_id' => 11,
'Name' => 'John Doe',
'Location' => 'Houston',
'date' => '2021-10-02'
],
[
'user_id' => 6,
'l_id' => 12,
'Name' => 'Rob Doe',
'Location' => 'Dallas',
'date' => '2021-10-02'
],
[
'user_id' => 6,
'l_id' => 13,
'Name' => 'Rob Doe',
'Location' => 'Philadelphia',
'date' => '2021-10-02'
],
];
I'm trying to display same user/day location record in one td by using following code:
$html = '';
foreach ($arr as $ar) {
if ($ar['date'] == $ar['date']) {
$html .= '<tr>
<td>' . $ar['Name'] . '</td>
<td>' . $ar['date'] . '</td>
<td>' . $ar['Location'] . '</td>
</tr>';
}
}
HTML:
<table>
<thead>
<tr>
<th>Name</th>
<th>Date</th>
<th>Location</th>
</tr>
</thead>
<tbody>
<?= $html; ?>
</tbody>
</table>
But it's repeating same date record multiple times (Name, Date):
Name Date Location
John Doe 2021-10-02 Chicago
John Doe 2021-10-02 Houston
Rob Doe 2021-10-02 Dallas
Rob Doe 2021-10-02 Philadelphia
And I want result like this:
Name Date Location
John Doe 2021-10-02 Chicago
Houston
--------------------------------------------
Rob Doe 2021-10-02 Dallas
Philadelphia
Use this function for creating your required data:
function arrayChanger($oldArray) {
$newArray = array();
foreach ($oldArray as $v) {
if (!isset($newArray[$v['user_id']])) {
$newArray[$v['user_id']] = array(
'user_id' => $v['user_id'],
'dataArray' => array()
);
}
$newArray[$v['user_id']]['dataArray'][] = array(
'l_id' => $v['l_id'],
'Name' => $v['Name'],
'Location' => $v['Location'],
'date' => $v['date'],
);
}
return $newArray;
}
And then you can use that by your array:
$html = '<table>
<thead>
<tr>
<th>Name</th>
<th>Date</th>
<th>Location</th>
</tr>
</thead>
<tbody>';
foreach (arrayChanger($arr) as $newArrayKey => $newArrayValue) {
if (count($newArrayValue['dataArray']) <= 1) {
$html .= '<tr>
<td>' . $value['Name'] . '</td>
<td>' . $value['date'] . '</td>
<td>' . $value['Location'] . '</td>
</tr>';
} else {
$i = 0;
foreach ($newArrayValue['dataArray'] as $key => $value) {
$html .= '<tr>';
($i === 0) ? $html .= '<td>' . $value['Name'] . '</td>' : $html .= '<td> </td>';
($i === 0) ? $html .= '<td>' . $value['date'] . '</td>' : $html .= '<td> </td>';
$html .= '<td>' . $value['Location'] . '</td>';
$html .= '</tr>';
$i = $i + 1;
}
}
}
$html .= '</tbody>
</table>';
The output would be as your need:
Name
Date
Location
John Doe
2021-10-02
Chicago
Houston
Rob Doe
2021-10-02
Dallas
Philadelphia
Edit:
As changes in question, I changed my answer so we have the function:
function arrayChanger($oldArray)
{
$newArray = array();
foreach ($oldArray as $v) {
if (!isset($newArray[$v['user_id']])) {
$newArray[$v['user_id']] = array(
'user_id' => $v['user_id'],
'l_id' => $v['l_id'],
'Name' => $v['Name'],
'date' => $v['date'],
'UserLocations' => array()
);
}
$newArray[$v['user_id']]['UserLocations'][] = array(
'Location' => $v['Location'],
);
}
return $newArray;
}
And after that creating the HTML:
$html = '<table>
<thead>
<tr>
<th>Name</th>
<th>Date</th>
<th>Location</th>
</tr>
</thead>
<tbody>';
foreach (arrayChanger($arr) as $newArrayKey => $newArrayValue) {
$html .= '<tr>
<td>' . $newArrayValue['Name'] . '</td>
<td>' . $newArrayValue['date'] . '</td>
<td>';
foreach ($newArrayValue['UserLocations'] as $key => $value) {
$html .= $value['Location'] . "<br>";
}
$html .= '</td>
</tr>';
}
$html .= '</tbody>
</table>';
The output will:
Name
Date
Location
John Doe
2021-10-02
ChicagoHouston
Rob Doe
2021-10-02
DallasPhiladelphia
You can make an new Array where you merge the date and location.
$newArr = [];
foreach($arr as $item) {
if(isset($newArr[$item['Name']])) {
$newArr[$item['Name']]['Location'][] = $item['Location'];
$newArr[$item['Name']]['date'][] = $item['date'];
} else {
$newArr[$item['Name']]['user_id'] = $item['user_id'];
$newArr[$item['Name']]['l_id'] = $item['l_id'];
$newArr[$item['Name']]['Name'] = $item['Name'];
$newArr[$item['Name']]['Location'] = [$item['Location']];
$newArr[$item['Name']]['date'] = [$item['date']];
}
}
print_r($newArr);
output would be:
Array
(
[John Doe] => Array
(
[user_id] => 5
[l_id] => 10
[Name] => John Doe
[Location] => Array
(
[0] => Chicago
[1] => Houston
)
[date] => Array
(
[0] => 2021-10-02
[1] => 2021-10-02
)
)
[Rob Doe] => Array
(
[user_id] => 6
[l_id] => 12
[Name] => Rob Doe
[Location] => Array
(
[0] => Dallas
[1] => Philadelphia
)
[date] => Array
(
[0] => 2021-10-02
[1] => 2021-10-02
)
)
)
Then you can use your loop. And for the elements date and location you can use the php implode (implode(',', [])) function. That will be the easiest way.
Try this code which print name and date only the first time:
$html = '';
$count=0;
foreach ($arr as $ar) {
if ($ar['date'] == $ar['date']) {
if($count == 0){
$html .= '<tr>
<td>' . $ar['Name'] . '</td>
<td>' . $ar['date'] . '</td>
<td>' . $ar['Location'] . '</td>
</tr>';
$count++;
}
else{
$html .= '<tr>
<td></td>
<td></td>
<td>' . $ar['Location'] . '</td>
</tr>';
$count=0;
}
}
}
Related
I have a multidimensional array of fruits below.
$fruits = [
'ORANGE' =>
[
'Size' => '0.20',
'Cost' => '0.49',
'Lbs.' => '0.60',
]
'LEMON' =>
[
'Size' => '0.15',
'Cost' => '0.29',
'Lbs.' => '0.20',
]
];
I want to display the fruit array like below, but it is not working as expected.
-----| ORANGE | LEMON |
Size | 0.20 | 0.15 |
Cost | 0.49 | 0.29 |
Lbs. | 0.60 | 0.20 |
My code below is not quite doing what I expected. Any suggestions? Thank you!
echo '<table id="fruits" style="width:400px;border:1px solid black;">' . PHP_EOL;
echo '<tbody>' . PHP_EOL;
foreach ($fruits as $fruitkey => $fruitvalue) {
echo '<th>' . $fruitkey . '</th>';
foreach ($fruitvalue as $key => $value) {
echo '<tr>' . PHP_EOL;
echo '<td>' . PHP_EOL;
echo $key . PHP_EOL;
echo '</td>' . PHP_EOL;
echo '<td>' . PHP_EOL;;
echo number_format($value, 2) . PHP_EOL;
echo '</td>' . PHP_EOL;
echo '</tr>' . PHP_EOL;
}
}
echo '</tbody>' . PHP_EOL;
echo '</table">' . PHP_EOL;
Can you try the below code
<?php
$fruits = [
'ORANGE' =>
[
'Size' => '0.20',
'Cost' => '0.49',
'Lbs.' => '0.60',
],
'LEMON' =>
[
'Size' => '0.15',
'Cost' => '0.29',
'Lbs.' => '0.20',
]
];
$keys = array_keys($fruits);
if(!empty($keys))
$innerKeys = array_keys($fruits[$keys[0]]);
echo '<table id="fruits" style="width:400px;border:1px solid black;">';
echo '<thead><tr>';
echo '<td>----</td>';
foreach($keys as $key)
echo '<td>'.$key.'</td>';
echo '</tr></thead>';
echo '<tbody>';
foreach($innerKeys as $inKey){
echo '<tr>';
echo '<td>'.$inKey.'</td>';
foreach($fruits as $fKey => $val){
echo '<td>'.$val[$inKey].'</td>';
}
echo '</tr>';
}
echo '</tbody>';
echo '</table>';
Demo Link
Consider the following $data array:
Array
(
[0] => Array
(
[code] => 20
[name] => Name 1
[month] => 4
[cost] => 100
..
..
)
[1] => Array
(
[code] => 30
[name] => Name 2
[month] => 3
[cost] => 120
..
..
)
[1] => Array
(
[code] => 30
[name] => Name 2
[month] => 6
[cost] => 180
..
..
)
..
..
)
Each array can have unknown number of codes. Each code has a different month ID. I want to sort and display the data so that there is just one row for the each code, and then in that row, display the value of the [cost] in the column number equal to the month. For example:
Column 1 2 3 4 5 6 7 8 9 10 11 12
Name 1 100
Name 2 120 180
Here's what I'm trying:
In order to find out how many rows should be printed, I fetch the unique code values:
$codes = array();
foreach( $data as $row ){
if ( in_array($row['code'], $codes) ) {
continue;
}
$codes[] = $row['code'];
}
Next, I use a loop to print the rows:
foreach( $codes as $code ){
//print 12 columns for each othe row
for ($i = 1; $<=12; $i++) {
//display column value if the code is same as the row
//and the month value is same as $i
//here's the problem
if (( $data['code'] == $code ) &&( $data['month'] == $i )) {
echo $data['cost'];
}
}
}
Problem/Question:
Do I need to put another loop inside the for loop to check if the $data['code'] == $code ? Or how can I do that?
I would use one loop to re-index the array:
$list = $codes = [];
for ($array as $item){
$list[$item['code']][$item['month']] = $item;
$codes[$item['code']] = $item['name'];
}
then use two loops to print:
for ($codes as $code => $codeName){
echo '<tr><th>', $codeName, '</th>';
for (range(1, 12) as $month){
echo '<td>', ($list[$code][$month]['cost'] ?? ''), '</td>;
}
echo '</tr>', "\n";
}
I really do not like the idea of if()s inside the loops.
I would suggest that you preprocess your data to a structured array first and then you print it, for example, indexed by code with a structure like:
[
['the code'] => [
'name' => '',
'months' => [
'6' => // cost
]
]
]
You can do it like this:
$items = [
[
'code' => 20,
'name' => 'Name 1',
'month' => 4,
'cost' => 100,
],
[
'code' => 30,
'name' => 'Name 2',
'month' => 3,
'cost' => 120,
],
[
'code' => 30,
'name' => 'Name 2',
'month' => 6,
'cost' => 180,
],
];
$sortedItems = [];
foreach ($items as $item) {
if (!isset($sortedItems[$item['code']])) {
$sortedItems[$item['code']] = [
'name' => $item['name'],
'months' => [],
];
}
$sortedItems[$item['code']]['months'][$item['month']] = $item['cost'];
}
You can the print it using a function similar to this:
function printItemsOf(array $list) {
echo '<table>';
// print header
echo '<tr>';
echo '<td>Column</td>';
for ($i = 1; $i <= 12; $i++) {
echo '<td>' . $i . '</td>';
}
echo '</tr>';
// print items
foreach ($list as $code => $item) {
echo '<tr>';
echo '<td>' . $item['name'] . '</td>';
for ($i = 1; $i <= 12; $i++) {
if (!isset($item['months'][$i])) {
echo '<td></td>';
} else {
echo '<td>' . $item['months'][$i] . '</td>';
}
}
echo '</tr>';
}
echo '</table>';
}
Which outputs:
<table border="1"><tr><td>Column</td><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td><td>7</td><td>8</td><td>9</td><td>10</td><td>11</td><td>12</td></tr><tr><td>Name 1</td><td></td><td></td><td></td><td>100</td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr><tr><td>Name 2</td><td></td><td></td><td>120</td><td></td><td></td><td>180</td><td></td><td></td><td></td><td></td><td></td><td></td></tr></table>
Actually This are my real data from API.
$main2 = array(
'sup1' => array(
'01-Jun-2019-TO-03-Jun-2019' => array("connection_count" => 54, "source_type" => 'TATA'),
'04-Jun-2019-TO-08-Jun-2019' => array("connection_count" => 10, "source_type" => 'Rel'),
),
'sup2' => array(
'01-Jun-2019-TO-03-Jun-2019' => array("connection_count" => 54, "source_type" => 'TCS'),
'04-Jun-2019-TO-08-Jun-2019' => array("connection_count" => 55, "source_type" => 'Jio'),
),
);
We need same out put using this array.
we create table all date in header like first key date as display in header.
-then data display supplier sup1 in first row
sup2 in second row row
like below out put
|Supplier Name |01-Jun-2019-TO-03-Jun-2019 |04-Jun-2019-TO-08-Jun-2019|<br/>
|sup1|54|TATA|10|Rel|
<br/>
|sup2|54|TCS|55|JIO|
Here is your code modified:
<?php
$main2 = array(
'01-Jun-2019-TO-03-Jun-2019' => array(
'sup1' => array("connection_count" => 54, "source_type" => 'TATA'),
'sup2' => array("connection_count" => 10, "source_type" => 'Rel'),
),
'04-Jun-2019-TO-08-Jun-2019' => array(
'sup1' => array("connection_count" => 54, "source_type" => 'TCS'),
'sup2' => array("connection_count" => 55, "source_type" => 'Jio'),
),
);
$suplist = array('sup1', 'sup2');
echo "<table border=1><tr>";
echo "<td>Supplier Name</td>";
foreach ($main2 as $key => $value) {
echo "<td colspan=2>" . $key . "</td>";
}
echo "</tr>";
foreach ($suplist as $supplier) {
echo "<tr><td>$supplier</td>";
foreach ($main2 as $value) {
echo "<td>" . $value[$supplier]['connection_count'] . "</td>";
echo "<td>" . $value[$supplier]['source_type'] . "</td>";
}
echo "</tr>";
}
echo "</table>";
And here is sample output (reformatted for clarity):
<table border=1>
<tr>
<td>Supplier Name</td>
<td colspan=2>01-Jun-2019-TO-03-Jun-2019</td>
<td colspan=2>04-Jun-2019-TO-08-Jun-2019</td>
</tr>
<tr>
<td>sup1</td>
<td>54</td>
<td>TATA</td>
<td>54</td>
<td>TCS</td>
</tr>
<tr>
<td>sup2</td>
<td>10</td>
<td>Rel</td>
<td>55</td>
<td>Jio</td>
</tr>
</table>
Here is your code which works with updated input data format:
$main2 = array(
'sup1' => array(
'01-Jun-2019-TO-03-Jun-2019' => array("connection_count" => 54, "source_type" => 'TATA'),
'04-Jun-2019-TO-08-Jun-2019' => array("connection_count" => 10, "source_type" => 'Rel'),
),
'sup2' => array(
'01-Jun-2019-TO-03-Jun-2019' => array("connection_count" => 54, "source_type" => 'TCS'),
'04-Jun-2019-TO-08-Jun-2019' => array("connection_count" => 55, "source_type" => 'Jio'),
),
);
$suppliers = array_keys($main2);
$dateRanges = [];
foreach ($main2 as $supplierData) {
$dateRanges = array_merge($dateRanges, array_keys($supplierData));
}
$dateRanges = array_values(array_unique($dateRanges));
sort($dateRanges);
echo "<table border=1><tr>";
echo "<td>Supplier Name</td>";
foreach ($dateRanges as $dateRange) {
echo "<td colspan=2>" . $dateRange . "</td>";
}
echo "</tr>";
foreach ($suppliers as $supplier) {
echo "<tr><td>$supplier</td>";
foreach ($dateRanges as $dateRange) {
if (isset($main2[$supplier][$dateRange])) {
echo "<td>" . $main2[$supplier][$dateRange]['connection_count'] . "</td>";
echo "<td>" . $main2[$supplier][$dateRange]['source_type'] . "</td>";
} else {
echo "<td></td><td></td>";
}
}
echo "</tr>";
}
echo "</table>";
And here is sample output (formatted for clarity):
<table border=1>
<tr>
<td>Supplier Name</td>
<td colspan=2>01-Jun-2019-TO-03-Jun-2019</td>
<td colspan=2>04-Jun-2019-TO-08-Jun-2019</td>
</tr>
<tr>
<td>sup1</td>
<td>54</td>
<td>TATA</td>
<td>10</td>
<td>Rel</td>
</tr>
<tr>
<td>sup2</td>
<td>54</td>
<td>TCS</td>
<td>55</td>
<td>Jio</td>
</tr>
</table>
I have an array like this:-
$str = array(
array(
'amount' => 1.87,
'user' => 'hello',
),
array(
'amount' => 0.9,
'user' => 'test',
),
array(
'amount' => 9,
'user' => 'hello',
),
array(
'amount' => 1.4,
'user' => 'test',
)
);
Now I show this data in HTML table like this for user 'test' :-
<thead>
<tr>
<th>Amount</th>
<th>User</th>
</thead>
<tbody>
<tr>
<td><?php
foreach ($str as $new_str) {
if ($new_str['user'] == "test") {
echo $new_str['amount'];
echo "<br />";
}
}
?></td><td><?php
foreach ($str as $new_str) {
if ($new_str['user'] == "test") {
echo $new_str['user'];
echo "<br />";
}
}
?></td>
</tr>
</tbody>
But now the problem is that when I use this code it shows the amount and user as a whole instead of two different rows. How can I fix this? Any help?
You just need to move your foreach loop outside of the <tr>...</tr> structure. This should work:
<?php foreach($str as $new_str){
if($new_str['user']=="test"){
echo "<tr><td>" . $new_str['amount'] . "</td><td>" . $new_str['user'] . "</td></tr>";
}
}
?>
Output (for your data)
<tr><td>0.9</td><td>test</td></tr>
<tr><td>1.4</td><td>test</td></tr>
Your tr was not repeating. output image I hope this will help.
<?php
$str = array(
array(
'amount' => 1.87,
'user' => 'hello',
),
array(
'amount' => 0.9,
'user' => 'test' ,
),
array(
'amount' => 9,
'user' => 'hello',
),
array(
'amount' => 1.4,
'user' => 'test',
)
);
?>
<table>
<thead>
<tr>
<th>Amount</th>
<th>User</th>
</tr>
</thead>
<tbody>
<?php foreach($str as $new_str) {
if($new_str['user'] == "test"){
echo '<tr>';
echo '<td>'.$new_str['amount'].'</td>';
echo '<td>'.$new_str['user'].'</td>';
echo '</tr>';
}
} ?>
</tbody>
</table>
I need to create and populate a table with a array... for now with some help from the bloggers goes like this:
<?php
$details = array(
1 => array(
1 => 1000,
2 => 'Company A',
3 => '2014-05-10',
4 => '10:00:00',
5 => '15:00:00',
),
2 => array(
1 => 2000,
2 => 'Company A',
3 => '2014-05-11',
4 => '10:00:00',
5 => '15:00:00',
),
3 => array(
1 => 3000,
2 => 'Company B',
3 => '2014-05-10',
4 => '10:00:00',
5 => '15:00:00',
),
4 => array(
1 => 4000,
2 => 'Company B',
3 => '2014-05-11',
4 => '16:00:00',
5 => '19:00:00',
)
);
// Format our data into something we can use more easily
$flight_dates = array();
$times = array();
$dates = array();
foreach ($details as $flight_details) {
$company_name = $flight_details[2];
$date = $flight_details[3];
$time = $flight_details[4] . ' - ' . $flight_details[5];
// Keep a unique record of each date, and the times of flights
$dates[$date] = 1;
$times[$time] = 1;
// Record which date/time each company is flying
$flight_dates[$date][$time][] = $company_name;
}
// Create the table header
$html = '<table border="1">';
$html .= '<thead>';
$html .= '<tr>';
$html .= '<th> </th>';
foreach ($dates as $date => $value1) {
$html .= '<th>' . $date . '</th>';
}
$html .= '</tr>';
// Create the rows in the table
foreach ($times as $time => $value1) { // Loop through each flight time
$html .= '<tr>';
$html .= '<td>' . $time . '</td>'; // The first column is always the time
foreach ($dates as $date => $value2) { // Loop through each date
if (!empty($flight_dates[$date][$time])) { // Check if flights exist at the current time
$html .= '<td>' . implode(', ', $flight_dates[$date][$time]) . '</td>'; // List companies
} else { // No flights
$html .= '<td> </td>'; // Leave cell blank
}
}
$html .= '</tr>';
}
$html .= '</table>';
echo $html;
?>
The result is this:
|....................|.. 2014-05-10 ........| 2014-05-11|
|10:00:00 - 15:00:00 | Company A, Company B | Company A |
|16:00:00 - 19:00:00 |......................| Company B |
I'm looking to get this:
|....................|2014-05-10 | 2014-05-11|
|10:00:00 - 15:00:00 | Company A | Company A |
|10:00:00 - 15:00:00 | Company B |...........|
|16:00:00 - 19:00:00 |...........| Company B |
In my idea the deal is: $times should have all the times for all the $flight_details array, and then we populate, will create a row for each $times record, that way we don't need to implode, just put the direct value off the array. The problem is to achieve this...
If you want such format, first off, you need to separate the headers, 2014-05-10 ... etc since they are above. Then you need to take care of the format. The key is: every time slot assign it to the company. Consider this example:
<?php
$details = array( 1 => array( 1 => 1000, 2 => 'Company A', 3 => '2014-05-10', 4 => '10:00:00', 5 => '15:00:00', ), 2 => array( 1 => 2000, 2 => 'Company A', 3 => '2014-05-11', 4 => '10:00:00', 5 => '15:00:00', ), 3 => array( 1 => 3000, 2 => 'Company B', 3 => '2014-05-10', 4 => '10:00:00', 5 => '15:00:00', ), 4 => array( 1 => 4000, 2 => 'Company B', 3 => '2014-05-11', 4 => '16:00:00', 5 => '19:00:00', ), 5 => array( 1 => 5000, 2 => 'Company C', 3 => '2014-05-10', 4 => '10:00:00', 5 => '15:00:00', ), 6 => array( 1 => 5000, 2 => 'Company D', 3 => '2014-05-12', 4 => '10:00:00', 5 => '15:00:00', ),);
//properly sort the raw data
// get headers
$header_dates = array();
foreach($details as $value) {
$header_dates[] = $value[3];
}
$header_dates = array_unique($header_dates);
// reformat main data companies
foreach($details as $key => $value) {
$time = "$value[4] - $value[5]"; // use this as key
foreach($header_dates as $date) {
// simple initialization
if(!isset($final[$value[2]][$time][$date])) $final[$value[2]][$time][$date] = '';
}
$final[$value[2]][$time][$value[3]] = $value[2];
// then set them accordingly to their date and time
}
?>
<!-- format them inside the table -->
<table border="1" cellpadding="10">
<!-- print the headers -->
<thead><tr><td></td><?php foreach($header_dates as $value): ?><th><?php echo $value; ?></th><?php endforeach; ?></tr></thead>
<tbody>
<?php foreach($final as $key => $data): ?>
<?php foreach($data as $index => $element): ?>
<tr><td><?php echo $index; ?></td> <!-- loop they time -->
<?php foreach($element as $v):?>
<td><?php echo $v; ?></td> <!-- values (Company A, ...) -->
<?php endforeach; ?>
</tr>
<?php endforeach; ?>
<?php endforeach; ?>
</tbody>
</table>
Sample Output
For the result to come like your expected one, you need to give:
<td>{explode("," $company_name)[0]}</td>
<td>{explode("," $company_name)[1]}</td>
In the headers, you need to give this way:
<td colspan="2">{$date}</td>
Note: The code I have provided is just a pseudo code. You need to write your own code. We can just guide you!