Creating select option value list from an array - php

I have an array like this (stored in the $optDir variable):
Array
(
[0] => Array
(
[id] => 8
[title] => Atasan Pria
[idparent] => 5
)
[1] => Array
(
[id] => 5
[title] => Fashion
[idparent] => 0
)
[2] => Array
(
[id] => 7
[title] => Motor
[idparent] => 0
)
[3] => Array
(
[id] => 6
[title] => Mobil
[idparent] => 0
)
[4] => Array
(
[id] => 9
[title] => Hem
[idparent] => 8
)
)
And i have PHP Codes like this :
function optCatAds($pos=0, $level=0){
global $optDir; $opt = "";
$n = count($optDir);
for($i=0;$i<$n;$i++){
$l = $level*3;
$sign=""; for ($z=0;$z<=$l;$z++){$sign.=" ";}
if($optDir[$i]['idparent']==$pos){
$opt .= '<option value="'.$optDir[$i][id].'">'.$sign.$optDir[$i][title].'</option>';
optCatAds($optDir[$i][id], $level + 1);
}
}
return $opt;
}
When i call the optCatAds function, give output like below:
<option value="5">Fashion</option>
<option value="6">Mobil</option>
<option value="7">Motor</option>
But, I want to made output like below :
<option value="5">Fashion</option>
<option value="8"> Atasan Pria</option>
<option value="9"> Hem</option>
<option value="6">Mobil</option>
<option value="7">Motor</option>
Conditions :
Fashion, Mobil, Motor <-- parent
Fashion have child Atasan Pria
Atasan Pria have child Hem
Can someone help me? Thank to your help.

This will work fine for you
$optDir = Array(Array("id"=>8,"title"=>"Atasan Pria","idparent"=>5),
Array("id"=>5,"title"=>"Fashion","idparent"=>0),
Array("id"=>7,"title"=>"Motor","idparent"=>0),
Array("id"=>6,"title"=>"Mobil","idparent"=>0),
Array("id"=>9,"title"=>"Hem","idparent"=>8)
);
function optCatAds($pos=0, $level=0)
{
global $optDir;$opt;
for($i=0;$i<count($optDir);$i++)
{
$l = $level*3;
$sign="";
for ($z=0;$z<$l;$z++){$sign.=" ";}
if($optDir[$i]['idparent']==$pos)
{
$opt .= '<option value="'.$optDir[$i]['id'].'">'.$sign.$optDir[$i]['title'].'</option>';
$opt .= optCatAds($optDir[$i]['id'], $level + 1);
}
}
return $opt;
}
$res = optCatAds($pos=0, $level=0);
echo "<select>{$res}</select>";

Can you try foreach instead of for loop ,
foreach($optDir as $k=>$value){
$opt .= '<option value="'.$value->id.'">'.$sign.$value->title.'</option>';
}

Replace $optDir[$i][title] with $optDir[$i]['title']
and $optDir[$i][id] with $optDir[$i]['id']
Here you are making recursive call so you can not get complete
function optCatAds($pos=0, $level=0){
global $optDir; $opt = "";
foreach($optDir as $each){
if($each['id']==8) $level = 2;
if($each['id']==9) $level = 3;
$l = $level*3;
$sign=""; for($z=0;$z<=$l;$z++){$sign.=" ";}
if($each['idparent']==$pos){
$opt .= '<option value="'.$each['id'].'">'.$sign.$each['title'].'</option>';
}
}
return $opt;
}

<?php
$optDir = Array(
Array(
'id' => 8,
'title' => 'Atasan Pria',
'idparent' => 5
),
Array(
'id' => 5,
'title' => 'Fashion',
'idparent' => 0
),
Array(
'id' => 7,
'title' => 'Motor',
'idparent' => 0
),
Array(
'id' => 6,
'title' => 'Mobil',
'idparent' => 0
),
Array(
'id' => 9,
'title' => 'Hem',
'idparent' => 8
)
);
function getOptionsRecursive($idParent = 0, $spaces = '') {
global $optDir;
$s = '';
for($i = 0 ; $i < sizeof($optDir) ; $i++) {
$current = $optDir[$i];
if($current['idparent'] == $idParent) {
$s .= '<option value="'.$current['id'].'">'.$spaces.$current['title'].'</option>';
$s .= getOptionsRecursive($current['id'], $spaces.' ');
}
}
return $s;
};
echo getOptionsRecursive();
?>

Related

Where to pass temp array when using recursive function?

I'm using a foreach loop inside my recursive function. But I have trouble figuring out where to pass my return statement. I need to return my temp array at some point, but I'm not sure how to do this:
<?php
$patterns = function($array, $temp = array(), $i = 0, $id = 0, $parent = 0) use(&$patterns) {
$return = null;
if(array_key_exists($i, $array)) {
foreach($array[$i] as $set) {
if($parent == $set['id']) {
$data = array(
'id' => $set['id'],
'parent' => $set['parent']
);
array_push($temp, $data);
}
$patterns($array, $temp, $i + 1, $set['id'], $set['parent']);
}
}
};
print_r($patterns($rev_relations));
?>
This is my data:
Array(
[0] => Array(
[0] => Array(
[id] => 60
[parent] => 55
)
[1] => Array(
[id] => 57
[parent] => 54
)
)
[1] => Array(
[0] => Array(
[id] => 61
[parent] => 50
)
[1] => Array(
[id] => 54
[parent] => 49
)
)
[2] => Array(
[0] => Array(
[id] => 49
[parent] => 0
)
)
)
<?php
//pass $temp by reference so outside variable gets populated
$patterns = function($array, &$temp, $i = 0, $id = 0, $parent = 0) use(&$patterns) {
$return = null;
if(array_key_exists($i, $array)) {
foreach($array[$i] as $set) {
if($parent == $set['id']) {
$data = array(
'id' => $set['id'],
'parent' => $set['parent']
);
array_push($temp, $data);
}
$patterns($array, $temp, $i + 1, $set['id'], $set['parent']);
}
}
};
//actuall array is created on temp here
$temp=array();
$patterns($rev_relations,$temp);
?>
wont this work? Never really worked with nameless functions, but this is how i would go about it on a normall recursive function
Ok, take two
<?php
$patterns = function($array, $temp = array(), $i = 0, $id = 0, $parent = 0) use(&$patterns) {
$return = null;
if(array_key_exists($i, $array)) {
foreach($array[$i] as $set) {
if($parent == $set['id']) {
$data = array(
'id' => $set['id'],
'parent' => $set['parent']
);
array_push($temp, $data);
}
return $patterns($array, $temp, $i + 1, $set['id'], $set['parent']);
}
}
else
{
return $temp;
}
};
$patterns($rev_relations);
?>

Implode multidimensional array with different glue in php

I have array like below:
Array
(
[22] => Array
(
[0] => 60
[29] => Array
(
[0] => 6
)
[30] => Array
(
[0] => 5
[1] => 8
)
[31] => Array
(
[0] => 7
[1] => 9
[2] => 14
[3] => 26
)
)
[23] => 12
[35] =>10
[42] =>22
)
now i want to implode array like
60[6][5||8][7||9||14||26]|12|10|22
I have tried below code:
$arr = array_map(function($el){ return $el['tag_id']; }, $arr);
$str = implode(',', $arr);
But it is not implode with required glue
How can i do it?
you can use this code
<?php
$a= Array(
22 => Array(
0 => 60,
29 => Array(
0 => 6
),
30 => Array
(
0 => 5,
1 => 8
),
31 => Array
(
0 => 7,
1 => 9,
2 => 14,
3 => 26
),
),
23 => 12,
35 =>10,
42 =>22,
);
$string='';
foreach($a as $arr){
if(is_array($arr)){
foreach($arr as $array){
if(is_array($array)){
$string .= '['.implode("||",$array).']';
}else{
if($string!==''){ $string .= '|';}
$string .= $array;
}
}
}else{
if($string!==''){ $string .= '|';}
$string .= $arr;
}
}
echo $string;die;
?>
Out put wil be
60[6][5||8][7||9||14||26]|12|10|22
Desired result without foreach.
$array = [
22 => [
0 => 60,
29 => [
0 => 6
],
30 => [
0 => 5,
1 => 8
],
31 => [
0 => 7,
1 => 9,
2 => 14,
3 => 26
]
],
23 => 12,
35 => 10,
42 => 22
];
$result = implode('|', array_map(function($item)
{
return is_array($item) // convert sub array into string
? implode('', array_map(function($inner_item)
{
return is_array($inner_item) // convert inner array into string
? '[' . implode('||', $inner_item) . ']'
: $inner_item;
}, $item))
: $item;
}, $array));
var_dump($result);
So, we have 3 types of delimiters: '|' - first level, ''(empty) - second level, '||' - third level.
You can use foreach and implode to achieve your pattern:
<?php
header('Content-Type: text/plain');
$arr = array();
$arr22 = array();
$arr22[0] = 60;
$arr22[29] = array(6);
$arr22[30] = array(5,8);
$arr22[31] = array(7,9,14,26);
$arr[22] = $arr22;
$arr[23] = 12;
$arr[35] = 10;
$arr[42] = 22;
$output = '';
foreach($arr as $entry) {
if(!is_array($entry)) {
$output .= $entry;
} else {
// array
foreach($entry as $inner) {
if(is_array($inner)) {
$output .= '[' . implode('||', $inner) . ']';
} else {
$output .= $inner;
}
}
}
$output .= '|';
}
echo substr($output, 0, strlen($output) - 1);
?>
which outputs:
60[6][5||8][7||9||14||26]|12|10|22
This should work for you:
Here the glue is configurable as you desired and this logic is built on the recursive call hence this will work for any level of multidimensional array:
<?php
$arrVal = array (
'22' => array(
'0' => 60,
'29' => array(
'0' => 6
),
'30' => array (
'0' => 5,
'1' => 8
),
'31' => array (
'0' => 7,
'1' => 9,
'2' => 14,
'3' => 26
)
),
'23' => 12,
'35' => 10,
'42' => 22
);
//60[6][5||8][7||9||14||26]|12|10|22
$constructedValue = "";
$glue = "||";
echo $constructedValue = implodeMultiArr($arrVal,$glue);
function implodeMultiArr($arrVal,$glue) {
$i = 0;
$constructedValue = "";
foreach ( $arrVal as $k=>$v) {
if ( is_array($v) ) {
$constructedValue .= !empty($constructedValue) ? "[".implodeMultiArr($v,$glue)."]" : implodeMultiArr($v,$glue)."]" ;
} else {
$constructedValue .= !empty($constructedValue) ? $glue.$v : $v ;
}
$i++;
}
return $constructedValue;
}

Dynamic Table from PHP Array

I am trying to display a multidimension php array as a table... can someone help?
This is my array:
Array
(
[1] => Array
(
[0] => Array
(
[c1] => UA07
[s1] => 6
[c2] => Ultimate Force
[s2] => 8
)
[1] => Array
(
[c1] => UF HEROES
[s1] => 6
[c2] => OLD School
[s2] => 4
)
[2] => Array
(
[c1] => Winners 05
[s1] => not_played
[c2] => World XI
[s2] => not_played
)
[3] => Array
(
[c1] => Outlaw
[s1] => 4
[c2] => UWK
[s2] => 3
)
)
[2] => Array
(
[0] => Array
(
[c1] => Ultimate Force
[s1] => 2
[c2] => UF HEROES
[s2] => 4
)
[1] => Array
(
[c1] => BY
[s1] => 0
[c2] => Outlaw
[s2] => 0
)
)
[3] => Array
(
[0] => Array
(
[c1] => UF HEROES
[s1] => 5
[c2] => Outlaw
[s2] => 1
)
)
)
This array currently contains 3 rounds, but could in theory contain more... and within each round it contains each game, and within each game it contains the results of those games...
C1/C2 are competitors and S1 / S2 are the scores...
How do I display each array in a column and move on to the next array and show them in columns as well.. lining them up like a tournament bracket
Any thoughts would be very helpful.
I am trying to achieve a format like this:
http://new.playdat.com/tournament-results.php "Bracket"
As others have said in the comments, you need a nested loop. Since you didn't specify a table format, I just created an example. You can run this at http://writecodeonline.com/php/
/** Simulating your data **/
$rounds = array();
$rounds[1][] = array('c1' => 'UA07', 's1' => 6, 'c2' => 'Ultimate Force', 's2' => 8);
$rounds[1][] = array('c1' => 'UF HEROES', 's1' => 6, 'c2' => 'Old School', 's2' => 4);
$rounds[2][] = array('c1' => 'Ultimate Force', 's1' => 2, 'c2' => 'UF HEROES', 's2' => 4);
$rounds[2][] = array('c1' => 'BY', 's1' => 0, 'c2' => 'Outlaw', 's2' => 0);
$table = <<<EOD
<table>
<thead>
<tr>
<th>Round</th>
<th>C1</th>
<th>S1</th>
<th>C2</th>
<th>S2</th>
</tr>
</thead>
<tbody>
EOD;
foreach ($rounds as $roundNum=> $round){
foreach ($round as $game) {
$table .= "<tr>";
$table .= "<td>{$roundNum}</td>";
$table .= "<td>{$game['c1']}</td>";
$table .= "<td>{$game['s1']}</td>";
$table .= "<td>{$game['c2']}</td>";
$table .= "<td>{$game['s1']}</td>";
$table .= "</tr>";
}
}
$table .= <<<EOD
</tbody>
</table>
EOD;
echo $table;
Dynamic tournament bracket:
Your array:
$rounds = array(
//Round 1
array(
array(
'c1' => 'UA07 ',
's1' => 6 ,
'c2' => 'Ultimate Force ',
's2' => 8 ,
),
array(
'c1' => 'UF HEROES',
's1' => 6,
'c2' => 'OLD School',
's2' => 4,
),
array(
'c1' => 'Winners 05 ',
's1' => 'not_played',
'c2' => 'World XI',
's2' => 'not_played',
),
array(
'c1' => 'Outlaw',
's1' => 4,
'c2' => 'UWK',
's2' => 3,
),
),
//Round 2
array(
array(
'c1' => 'Ultimate Force',
's1' => 2,
'c2' => 'UF HEROES',
's2' => 4,
),
array(
'c1' => 'BY',
's1' => 0,
'c2' => 'Outlaw',
's2' => 0,
),
),
//Round 3
array(
array(
'c1' => 'UF HEROES',
's1' => 5,
'c2' => 'Outlaw',
's2' => 1,
),
)
);
The generator:
$roundCount = 1;
$totalRounds = count($rounds);
echo '<table border="1"><tr>';
for($i = 1;$i <= $totalRounds;$i++)
{
echo '<td>Round'.$i.'</td>';
}
echo '</tr><tr>';
foreach($rounds as $round)
{
$matches = count($round);
echo '<td>';
foreach($round as $match)
{
echo $match['c1'].' - '.$match['s1'].'<br>';
echo $match['c2'].' - '.$match['s2'].'<br><hr>';
}
$roundCount++;
echo '</td>';
}
echo '</tr></table>';
Results:
Generator 2:
$roundCount = 1;
$totalRounds = count($rounds);
echo '<table border="1"><tr>';
for($i = 1;$i <= $totalRounds;$i++)
{
echo '<td>Round'.$i.'</td>';
}
echo '</tr><tr>';
foreach($rounds as $round)
{
$matches = count($round);
echo '<td>';
foreach($round as $match)
{
echo '<table border="1">';
echo '<tr><td>'.$match['c1'].'</td><td>'.$match['s1'].'</td></tr>';
echo '<tr><td>'.$match['c2'].'</td><td>'.$match['s2'].'</td></tr>';
echo '</table>';
}
$roundCount++;
echo '</td>';
}
echo '</tr></table>';
Generator with winner:
$roundCount = 1;
$totalRounds = count($rounds);
echo '<table border="1"><tr>';
for($i = 1;$i <= $totalRounds;$i++)
{
echo '<td>Round'.$i.'</td>';
}
echo '<td>Winner</td>';
echo '</tr><tr>';
foreach($rounds as $round)
{
$matches = count($round);
echo '<td>';
if($roundCount == $totalRounds)
{
if($round[0]['s1'] > $round[0]['s2']) {
$finalist = array($round[0]['c1'],$round[0]['s1']);
} else {
$finalist = array($round[0]['c2'],$round[0]['s2']);
}
}
foreach($round as $match)
{
echo '<table border="1">';
echo '<tr><td>'.$match['c1'].'</td><td>'.$match['s1'].'</td></tr>';
echo '<tr><td>'.$match['c2'].'</td><td>'.$match['s2'].'</td></tr>';
echo '</table>';
}
$roundCount++;
echo '</td>';
}
echo '<td>';
echo '<table border="1">';
echo '<tr><td>'.$finalist[0].'</td><td>'.$finalist[1].'</td></tr>';
echo '</table>';
echo '</td>';
echo '</tr></table>';

Hierarchy in the array РHP

I have a function that build a Tree Array. Example:
Array
(
[0] => Array
(
[id] => 12
[address] => 'Ukraine'
[parent_id] => 0
[children] => Array
(
[0] => Array
(
[id] => 11
[address] => Crimea
[parent_id] => 12
[children] => Array
(
[0] => Array
(
[id] => 16
[address] => Yalta
[parent_id] => 11
)
)
)
)
)
I have function to print Tree (I want to get output with levels indented):
function printTree($data) {
foreach ($data as $item) {
if ($item['parent_id'] != 0)
echo ' - ' . $item['address'] . "<br>";
else
echo $item['address'] . "<br>";
if (isset($item['children'])) {
printTree($item['children']);
}
}
}
But my result is only with one levels indets, because my if is not correct:
Ukraine
- Crimea
- Yalta
I need to get with all levels indents. What do I need to change in my if statement?
Ukraine
- Crimea
- Yalta
Rewrite your code this way:
function printTree($data, $level = 0) {
foreach ($data as $item) {
if ($item['parent_id'] != 0) {
/* here we corrects indent: */
echo str_repeat(' ', $level) . ' - ' . $item['address'] . "<br>";
} else {
echo $item['address'] . "<br>";
}
if (isset($item['children'])) {
printTree($item['children'], $level + 1);
}
}
}
You just add a depth variable to control how many blanks you want add before each child item:
<?php
$data = array(
0 => array(
'id' => 12,
'address' => 'Ukraine',
'parent_id' => 0,
'children' => array(
0 => array(
'id' => 11,
'address' => Crimea,
'parent_id' => 12,
'children' => array(
0 => array(
'id' => 16,
'address' => Yalta,
'parent_id' => 11,
)
)
)
)
)
);
printTree($data);
function printTree($data, $depth = 0) {
foreach ($data as $item) {
if ($item['parent_id'] != 0)
echo str_repeat(' ', $depth), "- {$item['address']}\n";
else
echo "{$item['address']}\n";
if (isset($item['children'])) {
printTree($item['children'], ++$depth);
}
}
}
Output:
Ukraine
- Crimea
- Yalta
Working demo.

PHP: reorder array to show hierarchy

How can I turn the first array in to the second one? The goal is to create an array that shows the hierarchy, based on location_id and parent_id. Each location_name should be in an array of which the key is its parent_id.
Ignore the values I gave to location_name. No value for parent_id == NULL, these are the top level items.
First array:
Array
(
[0] => stdClass Object
(
[location_id] => 1
[location_name] => Town 1
[parent_id] =>
)
[1] => stdClass Object
(
[location_id] => 2
[location_name] => Town 1.1
[parent_id] =>
)
[2] => stdClass Object
(
[location_id] => 3
[location_name] => Town 1.2
[parent_id] => 1
)
[3] => stdClass Object
(
[location_id] => 4
[location_name] => Town 1.3
[parent_id] => 1
)
[4] => stdClass Object
(
[location_id] => 5
[location_name] => town 1.1.1
[parent_id] => 2
)
[5] => stdClass Object
(
[location_id] => 6
[location_name] => Town 1.1.2
[parent_id] => 3
)
);
Resulting array should be:
Array(
'Town 1' = array(
'town 1.2',
'town 1.3' = array(
'town 1.1.2'
)
),
'Town 2' = array(
'town 1.1.1'
)
);
EDIT: working solution based on Rijk's answer
function _order_locs($parent, $array)
{
$return = array();
foreach ( $array as $town )
{
if ( $town->parent_id == $parent )
{
$set = $this->_order_locs( $town->location_id, $array );
if( $this->_menu_is_parent($town->location_id, $array) ) $return[$town->location_name] = $set;
else $return[] = $town->location_name;
}
}
return $return;
}
function _menu_is_parent($id, $array)
{
foreach( $array as $a )
{
if( $a->parent_id == $id ) return TRUE;
}
}
You have to loop through it, using a recursive function (one that calls itself):
function getChilds( $parent, $array ) {
$return = array();
foreach ( $array as $town ) {
if ( $town['location_id'] == $parent ) {
$return[] = array(
'name' => $town['location_name'],
'childs' => getChilds( $town['location_id'], $array )
);
}
}
return $return;
}
$towns_tree = getChilds( 0, $towns );
Might not work right off the bat, but that gives you a nice oppurtunity to play with the code and get familiar with this concept ;)
Here is some code that will more or less do what you need. You will have to tweak it to your liking.
<?php
Class Node {
public $id;
public $parent_id;
public $value;
public $children;
public $depth;
function __construct($id, $parent_id, $value) {
$this->id = $id;
$this->parent_id = $parent_id;
$this->value = $value;
$this->children = array();
$this->depth = 0;
}
function add_child(Node $new_child) {
if ($new_child->parent_id == $this->id) {
$this->children[$new_child->id] = $new_child;
$this->children[$new_child->id]->depth = $this->depth + 1;
} else {
foreach ($this->children as $child) {
$child->add_child($new_child);
}
}
}
function to_array() {
if (count($this->children) > 0) {
$arr = array();
foreach ($this->children as $child) {
array_push($arr, $child->to_array());
}
return array($this->value => $arr);
} else {
return $this->value;
}
}
function str() {
echo str_repeat(" ", $this->depth) . $this->value . "\n";
foreach ($this->children as $child) {
$child->str();
}
}
}
?>
Here is some sample code to test it with:
<?php
$arr = Array(
array('location_id' => 1,
'location_name' => 'Town 1',
'parent_id' => 0),
array('location_id' => 2,
'location_name' => 'Town 1.1',
'parent_id' => 0),
array('location_id' => 3,
'location_name' => 'Town 1.2',
'parent_id' => 1),
array('location_id' => 4,
'location_name' => 'Town 1.3',
'parent_id' => 1),
array('location_id' => 5,
'location_name' => 'Town 1.1.1',
'parent_id' => 2),
array('location_id' => 6,
'location_name' => 'Town 1.1.2',
'parent_id' => 3)
);
$root = new Node(0, 0, 'root');
foreach ($arr as $item) {
$node = new Node($item['location_id'],
$item['parent_id'],
$item['location_name']);
$root->add_child($node);
}
$tree = $root->to_array();
$tree = $tree['root'];
var_dump($tree);
?>

Categories