sort nested php array with two different values [duplicate] - php

This question already has answers here:
How can I sort arrays and data in PHP?
(14 answers)
Closed 8 years ago.
I'm trying to sort through an array first by [artist][0][name], then by [datetime] so I end up with something like
9/25 - Artist1
9/26 - Artist1
9/27 - Artist1
9/25 - Artist2
9/26 - Artist2
9/27 - Artist2
...
This is how I get the data from the feed:
Array
(
[0] => Array
(
[ticket_url] => ...
[on_sale_datetime] => ...
[ticket_status] => ...
[url] => ...
[venue] => Array
(
[longitude] => ...
[region] => ...
[city] => ...
[url] => ...
[country] => ...
[id] => ...
[latitude] => ...
[name] => ...
)
[artists] => Array
(
[0] => Array
(
[mbid] => ...
[url] => ...
[name] => ...
)
)
[datetime] => ...
[id] => ...
)
)
I can sort by [name] just fine but can't figure out how to get the [datetime] to go in order along with each [name]. Here's what I have so far:
$object = $x->eventSearch($artists, $location, null, "$today,$next_week", 1, 100);
$array = objectToArray($object);
usort($array, function($a, $b) {
return strcmp($a['artists'][0]['name'], $b['artists'][0]['name']);
});
foreach ($array as $key => $val)
{
$main_artist = $val[artists][0][name];
$dateofevent = date("m/d", strtotime($val[datetime]));
$venue_city = $val[venue][city];
$venue_region = $val[venue][region];
$venue_name = $val[venue][name];
?>
<tr>
<td><?php echo $dateofevent; ?></td>
<td><?php echo $main_artist; ?></td>
<td><?php echo $venue_city . ", " . $venue_region; ?></td>
<td><?php echo $venue_name; ?></td>
</tr>
<?php } ?>
Any insight would be greatly appreciated.

Do something like the following to sort by artist name, and then date/time.
usort($array, function($a, $b) {
$s = strcmp($a['artists'][0]['name'], $b['artists'][0]['name']);
if($s != 0 ) { return $s; }
datetime_comparison_here(); // your example data is helpfully '...'
});

Related

Creating table from multidimention array

I have multidimensional arrays with which I need to make a table in html. I have a problem with matching catalog numbers with dates in the table.
I created an array (little part of it below):
array cotains date => CatalogNo => [catalogNo],[count],[date]
Array
(
[2019/07/19] => Array
(
[71156] => Array
(
[catalogNo] => 71156
[count] => 22
[date] => 2019/07/19
)
[71157] => Array
(
[catalogNo] => 71157
[count] => 21
[date] => 2019/07/19
)
[71221] => Array
(
[catalogNo] => 71221
[count] => 217
[date] => 2019/07/19
)
)
[2019/07/18] => Array
(
[71156] => Array
(
[catalogNo] => 71156
[count] => 26
[date] => 2019/07/18
)
[71157] => Array
(
[catalogNo] => 71157
[count] => 25
[date] => 2019/07/19
)
[71221] => Array
(
[catalogNo] => 71221
[count] => 281
[date] => 2019/07/19
)
[71222] => Array
(
[catalogNo] => 71221
[count] => 173
[date] => 2019/07/19
)
...
I did something like this but this is just bad. I dont know how to do it actually.
$dane_arr <- this is the whole array
<table>
<tr>
<th>CatalogNo</th>
<?php
foreach( $dane_arr as $k => $v )
{
?>
<th><?php echo $k ?></th>
<?php
}
?>
</tr>
<?php
foreach( $dane_arr as $k_date => $date_ )
{
foreach( $date_ as $k_nrArt_ => $nrArt_ )
{ ?>
<tr>
<td><?php echo $nrArt_['catalogNo'] ?></td>
<td><?php echo $nrArt_['count'] ?></td>
</tr>
<?php
}
}
?>
`
There are duplicates in CatalogNo and of course dates doesn't fit.
I want to create table, something like that:
CatalogNo | 2019/07/18 | 2019/07/19 | ...
71156 26 22 ...
71157 25 21 ...
71221 281 217 ...
71222 173 0 ...
(Of course without duplicates in 'CatalogNo')
You would first need to rearrange your array. Then you get all dates, and create the table:
<?php
$catalogUsage = [];
foreach ($dane_arr as $date => $catalogs) {
foreach( $catalogs as $catalogNo => $catalog) {
$catalogUsage[$catalogNo][$date] = $catalog['count'];
}
}
$allDates = array_keys($dane_arr);
?>
<table>
<tr>
<th>CatalogNo</th>
<?php
foreach ($allDates as $date) {
echo "<th>$date</th>"
}
?>
</tr>
<?php
foreach($catalogUsage as $catalogNo => $counts)
{
echo "<tr><td>$catalogNo</td>";
foreach ($allDates as $date) {
echo "<td>" . (isset($counts[$date]) ? $counts[$date] : 0) . "</td>";
}
echo "</tr>";
}
?>
</table>
Code is untested, since I haven't got the original array, so bugs might exist. I just hope this gives you some new inspiration.

Group multidimensional array by key and sum values in PHP

There are similar questions on Stack Overflow but nothing quite like mine, and I also want to double check that I am doing this the most efficient way (resource wise).
I have surveys that are submitted and I want to tally the results. Each survey is saved in a multidimensional array like so:
Array ( [name] => Clark Kent [rating] => 5 )
These are coming from a loop as they are separate database entries.
So I am beginning by creating a new array with all these combined:
$mods = array();
$index = -1;
foreach($fields as $field) {
$index++;
$mods[$index]['name'] = $field['name'];
$mods[$index]['rating'] = $field['rating'];
}
Then I am grouping these so that all the ratings for the same name are together, so I can sum them later.
$groups = array();
foreach ($mods as $value) {
$groups[$value['name']][] = $value;
}
This produces the following:
Array (
[Clark Kent] => Array (
[0] => Array (
[name] => Clark Kent
[rating] => 5
)
[1] => Array (
[name] => Clark Kent
[rating] => 5
)
)
[Peter Parker] => Array (
[0] => Array (
[name] => Peter Parker
[rating] => 5
)
[1] => Array (
[name] => Peter Parker
[rating] => 5
)
)
[Bruce Wayne] => Array (
[0] => Array (
[name] => Bruce Wayne
[rating] => 5
)
[1] => Array (
[name] => Bruce Wayne
[rating] => 5
)
)
[Bruce Banner] => Array (
[0] => Array (
[name] => Bruce Banner
[rating] => 5
)
[1] => Array (
[name] => Bruce Banner
[rating] => 5
)
)
)
What I am trying to accomplish would be something like this:
<table>
<tr>
<td>Clark Kent</td>
<td>{average of all ratings}</td>
</tr>
</table>
I'm most of the way there, but I am stuck! I'm not sure how to get the grouped name that doesn't have any type of index or key so I can use that value for my table. Then I need to sum each grouped values.
I would do all the necessary math in the loop that reads the data from the database. Something like this:
$ratings = array();
while ($row = $result->fetch_assoc()) {
$name = $row['name'];
if (!isset($ratings[$name])) {
$ratings[$name] = array('count' => 1, 'sum' => $row['rating']);
}
else {
$ratings[$name]['count']++;
$ratings[$name]['sum'] += $row['rating'];
}
}
Then you can just output your table like so:
echo "<table>";
foreach ($ratings as $name => $r) {
echo "<tr><td>$name</td><td>" . round($r['sum'] / $r['count'], 1) . "</td></tr>";
}
echo "</table>";
To get average you can do something like:
foreach ($groups as $name => $group) {
$average = array_sum(array_column($group, 'rating')) / count($group);
echo $name;
}
You could simplify the problem in the first place in the structure you are using to handle those date
foreach($fields as $field) {
$mods[$field['name']][] = $field['rating'];
}
then just foreach with the key parameter
foreach($mods as $name => $mod) {
echo $name;
echo array_sum($mod) / count($mod);
}
Try to use the code below. Eliminating an extra loop to preparing group array.
$mods = array();
foreach($fields as $field) {
$mods[$field['name']][] = $field['rating'];
}
<table>
<tr>
<?php
if($mods) {
foreach($mods as $key=>$value) {
?>
<td><?php echo $key; ?></td>
<td><?php echo (array_sum($value)/count($value)); ?></td>
<?php
}
}
?>

Multidimensional array in PHP using foreach loop [duplicate]

This question already has answers here:
Looping a multidimensional array in php
(3 answers)
Closed last year.
Here is an array from which I need to sort out the dept name, the full name and the salary , whose salary are above 10000rs.
The array is:
Array
(
[PHP] => Array
(
[0] => Array
(
[name] => Jay
[salary] => 8000
)
[1] => Array
(
[name] => Raj
[salary] => 15000
)
[2] => Array
(
[name] => Mihir
[salary] => 12000
)
)
[Flex] => Array
(
[0] => Array
(
[name] => Vijay
[salary] => 14000
)
)
[System] => Array
(
[0] => Array
(
[name] => Kishan
[salary] => 5000
)
)
)
I am totally confused inside the loops of foreach and don't know how to call each value from the array.
My code allows me to display only names.
Can i know what is the best way to print and work with multidimensional arrays in PHP.
My code:
foreach($newArray as $x=>$x_value){
foreach ($x_value as $y=> $y_value){
if($y_value['salary']>10000)
echo $y_value['name']." has ". $y_value['salary']. ", ";
}
}
Use the following, Tested and working
$filterArray = array();
$i = 0;
foreach($salary as $dept => $employee){
foreach($employee as $index => $data){
if($data['salary'] > 10000){
$filterArray[$i]['deprtment'] = $dept;
$filterArray[$i]['name'] = $data['name'];
$filterArray[$i]['salary'] = $data['salary'];
}
$i++;
}
}
Result :-
Array
(
[1] => Array
(
[deprtment] => PHP
[name] => Raj
[salary] => 15000
)
[2] => Array
(
[deprtment] => PHP
[name] => Mihir
[salary] => 12000
)
[3] => Array
(
[deprtment] => Flex
[name] => Vijay
[salary] => 14000
)
)
Your input is nested array. So you have to use foreach +for loop:
$final_array = array();
foreach($newArray as $x=>$x_value)
{
foreach ($i=0;$i<count($x_value);$i++)
{
if($x_value[$i]['salary']>10000)
{
if(isset($final_array[$x]))
{
array_push($final_array[$x],array("name"=>$x_value[$i]['name'],"salary"=>$x_value[$i]['salary']));
}
else
{
$final_array[$x] = array();
array_push($final_array[$x],array("name"=>$x_value[$i]['name'],"salary"=>$x_value[$i]['salary']));
}
}
}
}
$final_array print dep wise name & salary which is max than 10000
Output :
Array
(
[PHP] => Array
(
[0]=> Array
(
[name] => Raj
[salary] => 15000
)
[1]=> Array
(
[name] => Mihir
[salary] => 12000
)
)
[Flex] => Array
(
[0]=> Array
(
[name] => Vijay
[salary] => 14000)
)
)
)
Here is a simpler solution for looping over the arrays.
foreach ($bigArray as $department => $employees) {
foreach ($employees as $employee) {
if ($employee["salary"] > 10000) {
echo "Department: " . $department;
echo "Employee: " . $employee;
echo "Salary: " . $salary;
} else {
echo $person . " has no money.";
}
}
}
This will output what you were trying to print in your example.
Output for the first employee:
Department: <department name>
Employee: Raj
Salary: 15000
In the future, you should include the department names in your example array since your example doesn't have all of the information you are trying to print; we can't print something that doesn't exist.
I don't know, if i've got you correctly, but if you need to filter out all the people from the sub-arrays (PHP, Flex, System, ...) and then sort them either by their name or salary, you could do it in this or a similar way:
$array = [
'PHP' => [
[
'name' => 'Jay',
'salary' => 8000
],
[
'name' => 'Raj',
'salary' => 15000
],
[
'name' => 'Mihir',
'salary' => 12000
]
],
'Flex' => [
[
'name' => 'Vijay',
'salary' => 14000
]
],
'System' => [
[
'name' => 'Kishan',
'salary' => 5000
]
]
];
$array_people = [];
$array_sorted = [];
$sort_by = 'name'; // Array key name
$sort_desc = false;
$min_salary = 10000;
foreach ($array as $type => $people)
{
foreach ($people as $info)
{
if ($info['salary'] >= $min_salary) {
$array_sorted[] = $info[$sort_by];
$array_people[] = $info;
}
}
}
if ($sort_desc) {
// Sort descending
arsort($array_sorted);
} else {
// Sort ascending
asort($array_sorted);
}
$array_final = [];
foreach (array_keys($array_sorted) as $index)
{
$array_final[] = $array_people[$index];
}
print_r($array_final);
Output:
Array
(
[0] => Array
(
[name] => Mihir
[salary] => 12000
)
[1] => Array
(
[name] => Raj
[salary] => 15000
)
[2] => Array
(
[name] => Vijay
[salary] => 14000
)
)
The first thing you need to do, is to process the main array in a way, that allows you to keep just the items you want - this items need to be stored in a different (empty) array (in this case $array_people).
While detecting the items you need, you've to get out all the values you want to sort by - this can be done at the same time. It's just about creating a new array which will contain just the values you will sort by (in this case $array_sorted).
Then comes the easier part. The next thing to do is sorting the array. There exist a bunch of functions, that can help you with this.
The functions i've used (asort and arsort) are keeping the original key of the item, so you can sort the array containing all the people by the keys of the sorted array (see the code up above).
And that's all, now you have an array with filtered and sorted people :) ... hope, this helps you.
Okay after reading so many solutions I personally believe that some of them are totally confusing for a newbie so here is the solution I actually implemented which is totally simple and easy to understand the flow of multi-dimensional array.
foreach($newArray as $x=>$x_value){
foreach ($x_value as $y=> $y_value){
if($y_value['salary']>10000){
echo "<tr>";
echo "<td>"; echo $y_value['name']; echo "</td>";
echo "<td>"; echo $x; echo "</td>";
echo "<td>"; echo $y_value['salary']; echo "</td>";
echo "</tr>";
}
}
}
The output will be like, (if u use table )

How to fix this `Illegal string offset` error in php?

I have a multidimensional array as below:
$rows[] = $row;
Now I want to create variable from looping this array. This is how I tried it:
foreach ($rows as $k => $value) {
//echo '<pre>',print_r($value).'</pre>';
$id = $value['news_id'];
$title = $value['news_title'];
echo $title;
}
But it produce an error as below:
...... Illegal string offset 'news_id'
This is the output of - echo '<pre>',print_r($value).'</pre>';
Array
(
[news_id] => 1110
[news_title] => test
[news] => test des
)
1
Array
(
[news_id] => 1109
[news_title] => ශ්‍රී ලංකාවේ ප්‍රථම....
[news] => දහසක් බාධක....
)
1
Can anybody tell me what is the wrong I have done?
UPDATE
output for echo '<pre>',print_r($rows).'</pre>';
Array
(
[0] =>
[1] => Array
(
[news_id] => 1110
[news_title] => test
[news] => test des
)
[2] => Array
(
[news_id] => 1109
[news_title] => ශ්‍රී ලංකාවේ ප්‍රථම....
[news] => දහසක් බාධක....
)
)
1
use isset function because your 0 index is empty in $row
foreach ($rows as $k => $value) {
if(isset($value['news_id'])){
$id = $value['news_id'];
$title = $value['news_title'];
echo $title;
}
}
you should add check (condition) when you assign data to $rows

Loop through json data from database on php page

I've this column in database table:
value=[
{"srno":1,
"name":"Gaspari Aminolast ",
"quantity":"2",
"price":"2920.0000",
"total_bill":5840
},
{"srno":2,
"name":"Gaspari Amino Max ",
"quantity":"2",
"price":"2640.0000",
"total_bill":5280
},
{"srno":3,
"name":"Myofusion 10Lbs",
"quantity":"2",
"price":"8400.0000",
"total_bill":16800}
]
And my php code is:
<?php
$getbill="select value from $tbl where bill_id='$_GET[id]' ";
$result=mysql_query($getbill)or die(mysql_error());
$results = array();
while($row=mysql_fetch_array($result))
{
$results[] = json_decode($row['value']);
}
print_r($results);
foreach($results as $key=>$value){
?>
<tbody>
<tr>
<td><?php echo $value['srno'];?></td>
<td><?php echo $value['name'];?></td>
<td><?php echo $value['quantity'];?></td>
<td><?php echo $value['price'];?></td>
<td ><?php echo $value['total_bill'];?></td>
</tr>
</tbody>
<?PHP
}
?>
I'm confused with how I loop through this and print all it contains.
print_r() :
Array (
[0] => Array (
[0] => stdClass Object (
[srno] => 1
[name] => Gaspari Aminolast
[quantity] => 2
[price] => 2920.0000
[total_bill] => 5840
)
[1] => stdClass Object (
[srno] => 2
[name] => Gaspari Amino Max
[quantity] => 2
[price] => 2640.0000
[total_bill] => 5280
)
[2] => stdClass Object (
[srno] => 3
[name] => Myofusion 10Lbs
[quantity] => 2
[price] => 8400.0000
[total_bill] => 16800
)
)
)
use second argument in json_decode function,set it to TRUE to get as array
$json='[{"srno":1,"name":"Gaspari Aminolast ","quantity":"2","price":"2920.0000","total_bill":5840},{"srno":2,"name":"Gaspari Amino Max ","quantity":"2","price":"2640.0000","total_bill":5280},{"srno":3,"name":"Myofusion 10Lbs","quantity":"2","price":"8400.0000","total_bill":16800}]';
echo '<pre>';print_r(json_decode($json,TRUE));
output:
Array
(
[0] => Array
(
[srno] => 1
[name] => Gaspari Aminolast
[quantity] => 2
[price] => 2920.0000
[total_bill] => 5840
)
[1] => Array
(
[srno] => 2
[name] => Gaspari Amino Max
[quantity] => 2
[price] => 2640.0000
[total_bill] => 5280
)
[2] => Array
(
[srno] => 3
[name] => Myofusion 10Lbs
[quantity] => 2
[price] => 8400.0000
[total_bill] => 16800
)
)
The array your trying to loop over seems to be in another array.
Try this or #RiggsFolly's answer
<table>
<?php
$getbill="select value from $tbl where bill_id='$_GET[id]' ";
$result=mysql_query($getbill)or die(mysql_error());
$results = array();
while($row=mysql_fetch_array($result))
{
$results = json_decode($row['value']);
}
print_r($results);
foreach($results as $key=>$value){
?>
<tr>
<td><?php echo $value['srno'];?></td>
<td><?php echo $value['name'];?></td>
<td><?php echo $value['quantity'];?></td>
<td><?php echo $value['price'];?></td>
<td ><?php echo $value['total_bill'];?></td>
</tr>
<?PHP
}
?>
</table>
If you notice, now I reformatted the value column, each value column contains a JSON string denoting an array of objects.
So for each value you store in the $results array you neeed to do another loop to examine the inner array of objects. Like so:
<?php
$getbill="select value from $tbl where bill_id='{$_GET[id]}' ";
$result=mysql_query($getbill)or die(mysql_error());
$results = array();
while($row=mysql_fetch_array($result))
{
$results[] = json_decode($row['value']);
}
print_r($results);
echo '<tbody>';
foreach($results as $value) :
foreach( $value as $object) :
?>
<tr>
<td><?php echo $object->srno;?></td>
<td><?php echo $object->name;?></td>
<td><?php echo $object->quantity;?></td>
<td><?php echo $object->price;?></td>
<td><?php echo $object->total_bill;?></td>
</tr>
<?php
endforeach;
endforeach;
?>
</tbody>
I also moved the <tbody> and </tbody> outside the loop as that would also have caused a problem with your layout.

Categories