Know the element level in multidimensional array - php

Well, I am here again dealing with arrays in php. I need your hand to guide me in the right direction. Suppose the following array:
-fruits
--green
---limon
---mango
--red
---apple
-cars
--ferrari
---enzo
----blue
----black
---318
--lamborg
---spider
---gallardo
----gallado-96
-----blue
-----red
-----gallado-98
The - (hyphen) symbol only illustrates the deep level.
Well, I need to build another array (or whatever), because it should be printed as an HTML select as below:
-fruits
--green
---limon
---mango
--red
---apple
-cars
--ferrari
---enzo
----blue
----black
---318
--lamborg
---spider
---gallardo
----gallado-96
-----blue
-----red
-----gallado-98
Looks that for each level element, it should add a space, or hyphen to determinate that it belongs to a particular parent.
EDIT
The have provide an answer provideng my final code. The html select element will display each level as string (repeating the "-" at the begging of the text instead multi-level elements.

Here's a simple recursive function to build a select dropdown given an array. Unfortunately I'm not able to test it, but let me know if it works. Usage would be as follows:
function generateDropdown($array, $level = 1)
{
if ($level == 1)
{
$menu = '<select>';
}
foreach ($array as $a)
{
if (is_array($a))
{
$menu .= generateDropdown($a, $level+1);
}
else
{
$menu .= '<option>'.str_pad('',$level,'-').$a.'</option>'."\n";
}
}
if ($level == 1)
{
$menu = '</select>';
}
return $menu;
}

OK, I got it with the help of #jmgardhn2.
The data
This is my array:
$temp = array(
array(
'name' => 'fruits',
'sons' => array(
array(
'name' => 'green',
'sons' => array(
array(
'name' => 'mango'
),
array(
'name' => 'banana',
)
)
)
)
),
array(
'name' => 'cars',
'sons' => array(
array(
'name' => 'italy',
'sons' => array(
array(
'name' => 'ferrari',
'sons' => array(
array(
'name' => 'red'
),
array(
'name' => 'black'
),
)
),
array(
'name' => 'fiat',
)
)
),
array(
'name' => 'germany',
'sons' => array(
array(
'name' => 'bmw',
)
)
),
)
)
);
Recursive function
Now, the following function will provide an array with items like [level] => [name]:
function createSelect($tree, $items, $level)
{
foreach ($tree as $key)
{
if (is_array($key))
{
$items = createSelect($key, $items, $level + 1);
}
else
{
$items[] = array('level' => $level, 'text' => $key);
}
}
return $items;
}
Calling the funcion
Now, call the function as below:
$items = createSelect($temp, array(), 0);
Output
If you iterate the final $items array it will look like:
1fruits
2green
3mango
3banana
1cars
2italy
3ferrari
4red
4black
3fiat
2germany
3bmw

Related

Foreach all of the nested loops automatically

guys I am trying to do this kind of loop.
$first_ex =
array(
'1st' => array(
'1.1' => 'value1',
'1.2' => 'value2'
// and so on...
)
);
$second_ex =
array(
'1st' => array(
'1.1' => array(
1.1.1 => 'value'
// so on...
)
'1.2' => array(
1.2.1 => 'value'
// so on...
)
)
);
As of now I can only do array in an array, but how can I make a code that it will automatically process all of the nested arrays no matter how many nested arrays are in there.
[Note] It does not answer my question.
function processArray($array) {
foreach ($array as $item) {
if (is_array($item)) {
processArray($item);
} else {
processValue($item);
}
}
}
function processValue($value) {
echo $value;
}
processArray($second_ex);

Get value of multidimensional array by other value

I've got a multidimensional PHP array in that form:
array(
(int) 0 => array(
'Category' => array(
'id' => '01',
'title' => 'SomeCategory'
)
),
(int) 1 => array(
'Category' => array(
'id' => '02',
'title' => 'OtherCategory'
)
)
)
I want to get the title of the category with a specific id, e.g. SomeCategory when I have the id 01.
Is there a better (more performant or easier) way to do it than this one?
foreach($categories as $nestedCategory) {
foreach($nestedCategory as $category) {
if($category['id'] === $postedData['Submission.Category.0.id']) {
debug($category['title']);
}
}
}
Thanks!
If the id's are unique you could rewrite the array
foreach( $array as $n => $item ) {
$arr[$item['Category']['id']] = $item;
}
// get id 02
echo $arr['02']['Category']['title']; // output: OtherCategory

Print arrays, subarrays and so forth

I have a multidimensional array which contains a bunch of categories. For this example, I've filled it with clothing categories.
$categories = array(
'Fashion' => array(
'Shirts' => array(
'Sleeve' => array(
'Short sleeve',
'Long sleeve'
),
'Fit' => array(
'Slim fit',
'Regular fit'
),
'Blouse'
),
'Jeans' => array(
'Super skinny',
'Slim',
'Straight cut',
'Loose',
'Boot cut / flare'
)
),
);
I want to be able to print this whole array like so:
--Fashion
----Shirts
-------Sleeve
---------Short sleeve
---------Long sleeve
-------Fit
---------Slim fit
---------Regular fit
----Blouse
I suppose I need to use some kind of recursive function.
How can I do this?
i've tried to use your given array and get this:
$categories = array(
'Fashion' => array(
'Shirts' => array(
'Sleeve' => array(
'Short sleeve',
'Long sleeve'
),
'Fit' => array(
'Slim fit',
'Regular fit'
),
'Blouse'
),
'Jeans' => array(
'Super skinny',
'Slim',
'Straight cut',
'Loose',
'Boot cut / flare'
)
),
);
showCategories($categories);
function showCategories($cats,$depth=1) { // change depth to 0 to remove the first two -
if(!is_array($cats))
return false;
foreach($cats as$key=>$val) {
echo str_repeat("-",$depth*2).(is_string($key)?$key:$val).'<br>'; // updated this line so no warning or notice will get fired
if(is_array($val)) {
$depth++;
showCategories($val,$depth);
$depth--;
}
}
}
will result in
--Fashion
----Shirts
------Sleeve
--------Short sleeve
--------Long sleeve
------Fit
--------Slim fit
--------Regular fit
------Blouse
----Jeans
------Super skinny
------Slim
------Straight cut
------Loose
------Boot cut / flare
A recursive function will serve your answer:
function printAll($a) {
if (!is_array($a)) {
echo $a, ' ';
return;
}
foreach($a as $k => $value) {
printAll($k);
printAll($value);
}
}
try this
<?php
function print_r_recursive($array){
if(!is_array($array)){
echo $array;
return; }
foreach ($array as $value) {
if(is_array($value)){
print_r_recursive($value);
}
}
}
?>

How to extract the relevant elements from this array of associative arrays?

I have the following challenging array of associative arrays in php.
array(
(int) 0 => array(
'table' => array(
'venue' => 'venue1',
'name' => 'name1'
)
),
(int) 1 => array(
'table' => array(
'venue' => 'venue1',
'name' => 'name2'
)
),
(int) 2 => array(
'table' => array(
'venue' => 'venue2',
'name' => 'name3'
)
),
(int) 3 => array(
'table' => array(
'venue' => 'venue3',
'name' => 'name4'
)
)
)
I want to extract a list of relevant names out based on the venue. I would like to implement a function ExtractNameArray($venue) such that when $venue=='venue1', the returned array will look like array('name1', 'name2')
I have been cracking my head over this. I am starting with $foreach and am stuck. How can this be done in php? Thank you very much.
first, you have to pass the array with the data to the function
second, the name of the function should start with lower character (php conventions)
try this
function extractNameArray($array, $venue) {
$results = array();
foreach($array as $key=>$value) {
if(isset($value['table']['venue'])&&$value['table']['venue']==$venue) {
isset($value['table']['name']) && $results[] = $value['table']['name'];
}
}
return $results;
}
function ExtractNameArray($venue)
{
$array = array(); // your array
$return_array = array();
foreach($array as $arr)
{
foreach($arr['table'] as $table)
{
if($table['venue'] == $venue)
{
$return_array[]['name'] = $table['name'];
}
}
}
return $return_array;
}
You must define $array with you array. Good Luck

Quick Recursive search of all indexes within an array

Ok, so say I have an array as follows:
$buttons = array(
'mlist' => array(
'title' => 'Members',
'href' => $scripturl . '?action=mlist',
'show' => $context['allow_memberlist'],
'sub_buttons' => array(
'mlist_view' => array(
'title' => 'View the Member List',
'href' => $scripturl . '?action=mlist',
'show' => true,
),
'mlist_search' => array(
'title' => 'Search for Members',
'href' => $scripturl . '?action=mlist;sa=search',
'show' => true,
'is_last' => true,
),
),
),
'home' => array(
'title' => 'Home',
'href' => $scripturl,
'show' => true,
'sub_buttons' => array(
),
'is_last' => $context['right_to_left'],
),
'help' => array(
'title' => 'Help',
'href' => $scripturl . '?action=help',
'show' => true,
'sub_buttons' => array(
),
),
);
I need to sort through this array and return all indexes of it in another array as an index, and the values of these arrays will be the title. So it should return an array as follows:
array(
'mlist' => 'Members',
'mlist_view' => 'View the Member List',
'mlist_search' => 'Search for Members',
'home' => 'Home',
'help' => 'Help',
);
How can this be achieved easily? Basically, need the key of each array if a title is specified and need to populate both within another array.
The following snippet loops over all of the arrays (recursively) to extract the key/title pairs.
$index = array();
$iterator = new RecursiveIteratorIterator(new ParentIterator(new RecursiveArrayIterator($buttons)), RecursiveIteratorIterator::SELF_FIRST);
foreach ($iterator as $key => $value) {
if (array_key_exists('title', $value)) {
$index[$key] = $value['title'];
}
}
var_dump($index);
How can this be achieved easily?
initialize an empty, new array
foreach the $buttons array with key and value
extract title from value
set the key in the new array with the title
done.
Edit: In case a recursive array iterator catches too much (identifying elements as children while they are not - just being some other array), and you don't want to write an extension of the recursive iterator class, stepping through all children can be solved with some "hand written" iterator like this:
$index = array();
$childKey = 'sub_buttons';
$iterator = $buttons;
while(list($key, $item) = each($iterator))
{
array_shift($iterator);
$index[$key] = $item['title'];
$children = isset($item[$childKey]) ? $item[$childKey] : false;
if ($children) $iterator = $children + $iterator;
}
This iterator is aware of the child key, so it will only iterate over childs if there are some concrete. You can control the order (children first, children last) by changing the order:
if ($children) $iterator = $children + $iterator;
- or -
if ($children) $iterator += $children;
I'm sure my answer is not most efficient, but using many foreach loops and if checks, it can be done. However, with my solution if you nested another array inside of say 'mlist_view' that you needed to get a title from, it would not work. My solution works for a max of 2 arrays inside of arrays within buttons. A better (and more general purpose solution) would probably involve recursion.
$result = array();
foreach($buttons as $field => $value) {
foreach($value as $nF => $nV) {
if($nF === 'title') {
$result[$field] = $nV;
}
if(is_array($nV)) {
foreach($nV as $name => $comp) {
if(is_array($comp)) {
foreach($comp as $nnF => $nnV) {
if($nnF === 'title') {
$result[$name] = $nnV;
}
}
}
}
}
}
}
foreach($result as $f => $v) {
echo $f.": ".$v."<br/>";
}
This works for your value of $buttons, fairly simple:
function get_all_keys($arr) {
if (!is_array($arr)) return array();
$return = array();
foreach (array_keys($arr) as $key) {
if (is_array($arr[$key])
&& array_key_exists('title', $arr[$key]))
$return[$key] = $arr[$key]['title'];
$return = array_merge($return, get_all_keys($arr[$key]));
}
return $return;
}
echo "<pre>";
print_r(get_all_keys($buttons));
echo "</pre>";
Which returns:
Array
(
[mlist] => Members
[mlist_view] => View the Member List
[mlist_search] => Search for Members
[home] => Home
[help] => Help
)

Categories