Loop through json array and group by key values - php

After json_decode I have the following Array :::
$json = Array ( [name] => Array ( [0] => Peter [1] => David ) [dep] => Array ( [0] => accounts [1] => sales ) [date] => Array ( [0] => 10/27/2015 [1] => 09/25/2015 ) );
How can I group the values by key so I get the following in a PHP foreach loop ? :::
<ul>
<li>Peter, accounts, 10/27/2015</li>
<li>David, sales, 09/25/2015</li>
</ul>
I've tried a similar foreach loop ( see below ) without the desired results, I'm able to print all the key & value's but I'm not able to group values by key eg. [1] :::
foreach($json as $row){
foreach($row as $key=>$val){
echo $key . ': ' . $val . '<br>';
}
}
Any assistance would be appreciated :::

You could use the following code to sort the list:
<?php
$json = [
"name" => ["Peter","David"],
"dep" => ["accounts", "sales"],
"date" => ["10/27/2015","09/25/2015"]
];
$final = [];
foreach($json as $section)
{
foreach($section as $key=>$info)
{
if(!isset($final[$key])) $final[$key] = "";
$final[$key] .= $info . ", ";
}
}
echo "<ul>";
foreach($final as $row)
{
echo "<li>" . substr($row, 0, strlen($row) - 2) . "</li>"; // -2 to remove the extra ", "
}
echo "</ul>";
?>
Result:
<ul>
<li>Peter, accounts, 10/27/2015</li>
<li>David, sales, 09/25/2015</li>
</ul>

Perhaps try something like this:
$arrayCount = count($json['name']);
$output = '<ul>';
for($i = 0; $i < $arrayCount; $i++) {
$output .= '<li>';
$output .= $json['name'][$i] . ', ';
$output .= $json['dep'][$i] . ', ';
$output .= $json['date'][$i];
$output .= '</li>';
}
$output .= '</ul>';
echo $output;
You would also be better off using an array format like this:
$json =
Array(
Array(
'name' => 'Peter',
'dep' => 'accounts',
'date' => '10/27/2015'
),
Array(
'name' => 'David',
'dep' => 'accounts',
'date' => '09/25/2015'
)
);
This is because you can create a easier to understand foreach loop like this:
$output = '<ul>';
foreach($json as $row) {
$output .= '<li>';
$output .= $row['name'] . ', ';
$output .= $row['dep'] . ', ';
$output .= $row['date'];
$output .= '</li>';
}
$output .= '</ul>';
echo $output;

Related

echoing out two dimensional associative arrays in php

I would like the data to be echoed out in this format
[0] - [name][description]
[1] - [name][description]
[2] - [name][description]
$options = array('guide_info' => $guide_info);
$guide_info = array( 'guide_name' => $guide_name,
'guide_description' => $guide_description
);
I created two foreach loops to try and echo out the name and description of each, like this:
foreach ($options as $key => $value) {
foreach ($guide_info as $type => $info){
$html .= $type . " " . $info . "\n";
}
}
but I receive errors about invalid argument supplied for foreach() on the second loop.
Currently my print_r($options) shows
Array ( [guide_name] => f
[guide_description] => fff
[0] => Array (
[guide_name] => fsss
[guide_description] => sssss
)
)
and my echo prints
guide_name fsss
guide_description sssss
guide_name fsss
guide_description sssss
guide_name fsss
guide_description sssss
How would I be able to echo out the correct information that print_r is showing?
Use a recursive function to echo out the name and description values in the desired format.
function process_array($arr, $counter){
foreach($arr as $key => $value){
if(is_array($value)){
process_array($value, ++$counter);
}else{
if($key == "guide_name"){
echo "[" . $counter . "] - [" . $value . "][";
}else{
echo $value . "]<br />";
}
}
}
}
// Here $options is your original array
process_array($options, 0);
Output:
[0] - [f][fff]
[1] - [fsss][sssss]
$guide_info = array( 'guide_name' => 'guid name',
'guide_description' => 'guid description',
);
$options = array('guide_info' => $guide_info);
foreach ($options as $key => $value) {
foreach($value as $a => $b) {
echo $a," =",$b ;
}
}
or for print_r
foreach ($options as $key => $value) {
print_r($value) ;
}
Why are you putting the $guide_info in $options.If you want all the entries from $guide_info, you can do this-
for($i = 0; $i < count($guide_info); $i++){
$html .= $type . " " . $info . "\n";
}
-> considering $guide_info is a multidimensional array like = array( [0] => 'guide_name' => $guide_name,
'guide_description' => $guide_description)
If for some reason $guide_info IS important, I would suggest it to be an indexed array not assoc.. Hope you find the solution :)

Echo multidimensional array in a html table

I am having a multidimensional array with same values like this,
[documents] => Array
(
[0] => Array
(
[doc_id] => 3
[doc_type] => driving_licence
[expiry_date] => 2015-11-26
[added_date] => 2015-11-16
)
[1] => Array
(
[doc_id] => 3
[doc_type] => driving_licence
[expiry_date] => 2015-11-26
[added_date] => 2015-11-16
)
)
So now I need to echo this array in a html table with single <tr>.
This is how I tried it :
foreach ($userData as $key => $value) {
$i=0;
foreach ($value['documents'] as $k => $v) {
$i++;
$html = "<tr>\n";
$html .= " <td class='center'>{$i}</td>";
$html .= " <td>{$v['doc_type']}</td>";
$html .= " <td>{$v['expiry_date']}</td>";
$html .= " <td>{$v['added_date']}</td>";
$html .= "</tr>\n";
echo $html;
}
}
But its repeating table <tr> with same values.
Can anybody tell me how to avoid this?
Thank you.
As requested, here is an example for you.
$userData = $input = array_map("unserialize", array_unique(array_map("serialize", $userData)));
foreach ($userData as $key => $value) {
$i=0;
foreach ($value['documents'] as $k => $v) {
$i++;
$html = "<tr>\n";
$html .= " <td class='center'>{$i}</td>";
$html .= " <td>{$v['doc_type']}</td>";
$html .= " <td>{$v['expiry_date']}</td>";
$html .= " <td>{$v['added_date']}</td>";
$html .= "</tr>\n";
echo $html;
}
}
That will give you a table with 1 <tr> row.
this is the way i would do what you are trying to do:
$movies = array
(
array('Office Space' , 'Comedy' , 'Mike Judge' ),
array('Matrix' , 'Action' , 'Andy / Larry Wachowski' ),
array('Lost In Translation' , 'Comedy / Drama' , 'Sofia Coppola' ),
array('A Beautiful Mind' , 'Drama' , 'Ron Howard' ),
array('Napoleon Dynamite' , 'Comedy' , 'Jared Hess' )
);
echo "<table border=\\"1\\">";
echo "<tr><th>Movies</th><th>Genre</th><th>Director</th></tr>";
for ( $row = 0; $row < count($movies); $row++ )
{
echo "<tr><td>";
for ( $column = 0; $column < count($movies); $column++ )
{
echo $movies[$row][$column] ;
}
echo "<td></tr>";
}

PHP sort array by key 'value'

I have the following code which displays the results that I want. I'm trying to get it to sort on the key 'value' from the output below. So Eric, Eric 2, Eric 3
An example output of $resultnames is:
Array
(
[0] => Array
(
[Eric 2] => Asdf
)
[1] => Array
(
[Eric] => Asdf
)
[2] => Array
(
[Eric 3] => Asdf
)
)
So the key is the first name and the value of that key is the last name. I'm trying to sort the array by first name
foreach (array_chunk($uvugroups, 6, true) as $uvugroup)
{
foreach ($uvugroup as $uvustate) {
echo "<h4>Registrants</h4>";
$fnames = explode( '|', $uvustate['fname'] );
$lnames = explode( '|', $uvustate['lname'] );
$resultnames = array();
foreach ($fnames as $i => $key) {
$resultnames[] = array($key => $lnames[$i]);
}
foreach ($resultnames as $resultname) {
foreach ($resultname as $fkey => $lkey) {
echo "<ul>";
echo "<li>" . $fkey . " " . substr($lkey,0,1) . ".</li>";
echo "</ul>";
}
}
}
}
I tried to use ksort in different places in the code, but it didn't seem to have an effect.
It's a bit hard because the expected output is not defined in the question, but with this code as the contents of the second foreach it should produce a list sorted by first name.
$fnames = explode( '|', $uvustate['fname'] );
$lnames = explode( '|', $uvustate['lname'] );
$resultnames = array_combine($fnames, $lnames);
ksort($resultnames);
echo "<ul>";
foreach ($resultnames as $fkey => $lkey) {
echo "<li>" . $fkey . " " . substr($lkey,0,1) . ".</li>";
}
echo "</ul>";

Imploding with "and" in the end?

I have an array like:
Array
(
[0] => Array
(
[kanal] => TV3+
[image] => 3Plus-Logo-v2.png
)
[1] => Array
(
[kanal] => 6\'eren
[image] => 6-eren.png
)
[2] => Array
(
[kanal] => 5\'eren
[image] => 5-eren.png
)
)
It may expand to several more subarrays.
How can I make a list like: TV3+, 6'eren and 5'eren?
As array could potentially be to further depths, you would be best off using a recursive function such as array_walk_recursive().
$result = array();
array_walk_recursive($inputArray, function($item, $key) use (&$result) {
array_push($result, $item['kanal']);
}
To then convert to a comma separated string with 'and' separating the last two items
$lastItem = array_pop($result);
$string = implode(',', $result);
$string .= ' and ' . $lastItem;
Took some time but here we go,
$arr = array(array("kanal" => "TV3+"),array("kanal" => "5\'eren"),array("kanal" => "6\'eren"));
$arr = array_map(function($el){ return $el['kanal']; }, $arr);
$last = array_pop($arr);
echo $str = implode(', ',$arr) . " and ".$last;
DEMO.
Here you go ,
$myarray = array(
array(
'kanal' => 'TV3+',
'image' => '3Plus-Logo-v2.png'
),
array(
'kanal' => '6\'eren',
'image' => '6-eren.png'
),
array(
'kanal' => '5\'eren',
'image' => '5-eren.png'
),
);
foreach($myarray as $array){
$result_array[] = $array['kanal'];
}
$implode = implode(',',$result_array);
$keyword = preg_replace('/,([^,]*)$/', ' & \1', $implode);
echo $keyword;
if you simply pass in the given array to implode() function,you can't get even the value of the subarray.
see this example
assuming your array name $arr,codes are below
$length = sizeof ( $arr );
$out = '';
for($i = 0; $i < $length - 1; $i ++) {
$out .= $arr [$i] ['kanal'] . ', ';
}
$out .= ' and ' . $arr [$length - 1] ['kanal'];
I think it would work to you:
$data = array(
0 =>['kanal' => 'TV1+'],
1 =>['kanal' => 'TV2+'],
2 =>['kanal' => 'TV3+'],
);
$output = '';
$size = sizeof($data)-1;
for($i=0; $i<=$size; $i++) {
$output .= ($size == $i && $i>=2) ? ' and ' : '';
$output .= $data[$i]['kanal'];
$output .= ($i<$size-1) ? ', ' : '';
}
echo $output;
//if one chanel:
// TV1
//if two chanel:
// TV1 and TV2
//if three chanel:
// TV1, TV2 and TV3
//if mote than three chanel:
// TV1, TV2, TV3, ... TV(N-1) and TV(N)
$last = array_slice($array, -1);
$first = join(', ', array_slice($array, 0, -1));
$both = array_filter(array_merge(array($first), $last));
echo join(' and ', $both);
Code is "stolen" from here: Implode array with ", " and add "and " before last item
<?php
foreach($array as $arr)
{
echo ", ".$arr['kanal'];
}
?>

Creating php arrays from sql queries

I'm trying to create an array of arrays so I can build a dynamic menu, but I'm getting lost amongst the code. My output looks like this:
$menu = Array (
[0] => Array (
[text] => Home
[class] => 875
[link] => //Home
[show_condition] => TRUE
[parent] => 0
)
[1] => Array (
[text] => About
[class] => 326
[link] => //About
[show_condition] => TRUE
[parent] => 0
)
etc
etc
etc
[339] => Array (
[text] => Planner
[class] => 921
[link] => //Planner
[show_condition] => TRUE
[parent] => 45
)
)
And the two functions which should build the menu are:
function build_menu ( $menu ) {
$out = '<div class="container4">' . "\n";
$out .= ' <div class="menu4">' . "\n";
$out .= "\n".'<ul>' . "\n";
for ( $i = 1; $i <= count ( $menu )-1; $i++ )
{
if ( is_array ( $menu [ $i ] ) ) {//must be by construction but let's keep the errors home
if ( $menu [ $i ] [ 'show_condition' ] && $menu [ $i ] [ 'parent' ] == 0 ) {//are we allowed to see this menu?
$out .= '<li class="' . $menu [ $i ] [ 'class' ] . '"><a href="' . $menu [ $i ] [ 'link' ] . '">';
$out .= $menu [ $i ] [ 'text' ];
$out .= '</a>';
$out .= get_childs ( $menu, $i );
$out .= '</li>' . "\n";
}
}
else {
die ( sprintf ( 'menu nr %s must be an array', $i ) );
}
}
$out .= '</ul>'."\n";
$out .= "\n\t" . '</div>';
return $out . "\n\t" . '</div>';
}
function get_childs ( $menu, $el_id ) {
$has_subcats = FALSE;
$out = '';
$out .= "\n".' <ul>' . "\n";
for ( $i = 1; $i <= count ( $menu )-1; $i++ )
{
if ( $menu [ $i ] [ 'show_condition' ] && $menu [ $i ] [ 'parent' ] == $el_id ) {//are we allowed to see this menu?
$has_subcats = TRUE;
$add_class = ( get_childs ( $menu, $i ) != FALSE ) ? ' subsubl' : '';
$out .= ' <li class="' . $menu [ $i ] [ 'class' ] . $add_class . '"><a href="' . $menu [ $i ] [ 'link' ] . '">';
$out .= $menu [ $i ] [ 'text' ];
$out .= '</a>';
$out .= get_childs ( $menu, $i );
$out .= '</li>' . "\n";
}
}
$out .= ' </ul>'."\n";
return ( $has_subcats ) ? $out : FALSE;
}
But the menu is refusing to show any submenu levels - it only displays top level. Any ideas?
Thanks!
Your code is almost there - you may want to change mysql_fetch_array to mysql_fetch_assoc, and you can convert values as returned into the appropriate types using functions like intval:
$menu = array();
$sql = "SELECT TabName as text, TabID as class, TabPath as link, IsVisible as show_condition, ParentId as parent FROM dnn_SMA_Tabs WHERE PortalID = 3 AND IsVisible = 'True' ORDER BY TabOrder ASC";
$result = mysql_query($sql);
$index = 1;
while($row = mysql_fetch_assoc($result)) {
$row['parent'] = intval($row['parent']);
$menu[$index] = $row;
$index++;
}
You'll need to convert show_condition to the appropriate type - how to do that probably depends on what column type IsVisible is.
i see your array has indexes from [0] to [399]
Array (
[0] => Array (
[text] => Home
[class] => 875
[link] => //Home
[show_condition] => TRUE
[parent] => 0
)
[1] => Array (
[text] => About
[class] => 326
[link] => //About
[show_condition] => TRUE
[parent] => 0
)
etc
etc
etc
[339] => Array (
[text] => Planner
[class] => 921
[link] => //Planner
[show_condition] => TRUE
[parent] => 45
) )
but you try to show items from [1] to [340]
for ( $i = 1; $i <= count ( $menu ); $i++ )
count($menu) returns 340 ([0]->[399])
Solution: for ( $i = 0; $i < count ( $menu ); $i++ )
start from 0 and go until 399 (strictly < 340)
I would do it in an other way: object oriented.
class Menu {
private $children = array();
private $name = '';
private $link = '';
private $class = '';
private $show = TRUE;
function __construct($name, $class, $link, $show = TRUE, $parent = null) {
$this->name = $name;
$this->link = $link;
$this->class = $class;
$this->show = $show;
if(!is_null($parent)) {
$parent->addChild($this);
}
}
function addChild(Menu $child) {
$this->children[] = $child;
}
// ... remaining getters (and probably setters)
}
Then you can build the menu like this:
$home = new Menu('Home', '875', '//Home');
$about = new Menu('About', '326', '//About');
//...
$planner = new Menu('Planner', '921', '//Planner', true, $home);
$menu = array($home, $about,...);
This is just one example. I am aware that this would mean you create 340 variables to hold your menu. With other setter and getter methods you can do it better, this is just a fast 'sketch'.
You can build the menu like this:
function build_menu ( $menu, $showContainer = false) {
$out = '';
if($showContainer) {
$out = '<div class="container4">' . "\n";
$out .= ' <div class="menu4">' . "\n";
}
if(!empty($menu)) {
$out .= '<ul>' . "\n";
for ($entry in $menu) {
if($entry->getShow()) {//are we allowed to see this menu?
$out .= '<li class="' . $entry->getClass() . '"><a href="' . $entry->getLink() . '">';
$out .= $entry->getText();
$out .= '</a>';
$out .= "\n" . build_menu($entry->getChildren());
$out .= '</li>' . "\n";
}
}
$out .= '</ul>'."\n";
}
if($showContainer) {
$out .= "\n\t" . '</div>';
$out .= "\n\t" . '</div>';
}
return $out;
}
I didn't test the code, but this is the idea behind it. If you have no experience with OOP and php have a look at the official documentation.
And also note that this requires PHP5.

Categories