How to merge php array - php

PHP Original array is a two-dimensional array.
I want to extract all the different value(the key name is parentMenu) to be a new two-dimensional array's key name
at the same time old array will be the new array's value
what and how should id do?
below is array example
//the menuList is get from mysql result
$menuList = array(
0=>array(
'navId' =>1,
'parentMenu' => 'HOME', //Previous Menu
'subMenu' => 'SHOW USER', //Sub Menu
'ctrl' => 'Index',
'action' => 'index'
),
1=>array(
'navId' =>2,
'parentMenu' => 'HOME',
'subMenu' => 'MODIFY PASSWORD',
'ctrl' => 'Modify',
'action' => 'index'
),
2=>array(
'navId' =>3,
'parentMenu' => 'ITEM LIST',
'subMenu' => 'CURRENT LIST',
'ctrl' => 'Current',
'action' => 'index'
),
3=> array(
'navId' =>4,
'parentMenu' =>'ITEM LIST',
'subMenu' =>'HISTORY LIST',
'ctrl' =>'History',
'action' =>'index'
)
);
//After processing the menuList
//The new MenuList what I want is like below
$newMenu = array(
/*parentMenu's value to be key*/
'HOME'=>array( array('navId' =>1,'subMenu' =>'SHOW USER' ,'ctrl' =>'Index' ,'action' =>'index'),
array('navId' =>2,'subMenu' =>'MODIFY PASSWORD','ctrl' =>'Modify' ,'action' =>'index')
),
'ITEM LIST'=>array(
array('navId' =>3,'subMenu' =>'CURRENT LIST','ctrl' =>'Current' ,'action' =>'index'),
array('navId' =>4,'subMenu' =>'HISTORY LIST','ctrl' =>'History' ,'action' =>'index')
)
);

$newMenu = array();
foreach($menuList as $item) {
$key = $item['parentMenu'];
unset($item['parentMenu']); // remove the parentMenu
if(!isset($newMenu[$key])) {
$newMenu[$key]] = array($item);
} else {
//array_push($newMenu[$key], $item);
$newMenu[$key][] = $item;
}
}
UPDATE: adjusted codes according to #Anyone's suggestion

Related

How to get a specific value based on adjacent key from a keyless multidimensional array?

Consider the following array:
$serviceNames = array(
0 => array(
'language' => 'en',
'value' => 'something',
'type' => 'name',
),
1 => array(
'language' => 'fi',
'value' => 'jotain',
'type' => 'name',
),
2 => array(
'language' => 'sv',
'value' => 'någonting',
'type' => 'name',
),
);
I need to get the 'value' definitions based on language. The problematic part is that the array $serviceNames does not have a predefined length (comes originally as a JSON file from an API), and the items can come in any order (in my example it goes like en, fi, sv, but it could be de, en, sv, fr... you get it).
If I wanted to get 'value' within the array where 'language' equals to 'en', how could I do that?
My advice is that you make the array associative.
Once that is done you access the value by ["language"]["value"].
$serviceNames = array_column($serviceNames, Null, "language");
echo $serviceNames["fi"]["value"]; //jotain
echo $serviceNames["en"]["value"]; //something
echo $serviceNames["sv"]["value"]; //någonting
https://3v4l.org/ssGQa
You can array_search() and array_column() function. first find the key where "en" is in the array then get the value.
$key = array_search('en', array_column($serviceNames, 'language'));
echo $serviceNames[$key]['value'];
Demo
simple:
$serviceNames = array(
0 => array(
'language' => 'en',
'value' => 'something',
'type' => 'name',
),
1 => array(
'language' => 'fi',
'value' => 'jotain',
'type' => 'name',
),
2 => array(
'language' => 'sv',
'value' => 'någonting',
'type' => 'name',
),
);
function myfunction(array $serviceNames, $field)
{
foreach($serviceNames as $service)
{
if ( $service['language'] === $field )
return $service['value'];
}
return false;
}
echo myfunction($serviceNames, 'en');
Output will : something
you would have to go through each elements of the array, using the foreach statement.
something like:
function getValueForLang($lang, array $arr)
{
foreach ($arr as $desc) {
if ($desc['language'] == $lang) {
return $arr['value'];
}
}
return null;
}
getValueForLang('en', $serviceNames); // gets your value, null if not found
see also:
https://secure.php.net/manual/en/control-structures.foreach.php

push one more element to array php

I have an array like this:
return array(
'User Management -> Role Management' => array(
array(
'permission' => 'role-management.view',
'label' => 'View',
),
array(
'permission' => 'role-management.create',
'label' => 'Create',
),
array(
'permission' => 'role-management.edit',
'label' => 'Edit',
),
array(
'permission' => 'role-management.delete',
'label' => 'Delete',
),
),
'User Management -> User Management' => array(
array(
'permission' => 'user-management.view',
'label' => 'View',
),
array(
'permission' => 'user-management.create',
'label' => 'Create',
),
array(
'permission' => 'user-management.edit',
'label' => 'Edit',
),
array(
'permission' => 'user-management.delete',
'label' => 'Delete',
),
),
);
I have accessed this array successfully like this:
$permissions = Config::get('permissions');
I want to add new index below label. I have tried this but could not add.
`foreach ($permissions as $permission) {
foreach ($permission as $eachPermission) {
$encodedPermission = base64_encode($eachPermission['permission']);
// $eachPermission['encodedPermission'] = $encodedPermission;
array_push($eachPermission, "encodedPermission", $encodedPermission);
}
}
var_dump($permissions); `
I have tried these but could not set the new index. My expected result was this:
'permission' => 'role-management.view',
'label' => 'View',
'encodedPermission' => 'someencodedstring'
Am I doing it wrong or missing something.
Your array is multi-level, so you need to do double-foreach to reach the level required for your changes.
And for your changes being saved in the original array, you need to use ampersand (&) before your iterators to keep the reference to the original array. Without it, you would insert the new data only to the copy of the array that was created for your foreach loop.
This works:
foreach ($permissions as &$eachPermission) {
foreach ($eachPermission as &$singlePermission) {
$encodedPermission = base64_encode($singlePermission['permission']);
array_push($singlePermission, "encodedPermission", $encodedPermission);
}
}
var_dump($permissions);
i would do it like this just because it is easier to understand ...
foreach($permissions as $name1=>$ar1){
foreach($ar1 as $name2=>$ar2){
$permissions[$name1][$name2]['encodedPermission'] = base64_encode($ar2['permission']);
}
}

Php recursive array counting

I'm trying to write a function which counts array elements recursively.
But result is false.
What could it be problem?
$schema = array(
'div' => array(
'class' => 'lines',
'div' => array(
'span' => array(
'key' => 'Product Name'
),
'val' => 'Soap'
),
'layer' => array(
'span' => array(
'key' => 'Product Name'
),
'val' => 'Ball'
)
)
);
function count_r($array, $i = 0){
foreach($array as $k){
if(is_array($k)){ $i += count_r($k, count($k)); }
else{ $i++; }
}
return $i;
}
echo count_r($schema);
This is the second result on Google so I'm adding this as a reference. There is already a built-in function in PHP that you can use: count().
You can use it like this:
count($schema, COUNT_RECURSIVE);
This function can also detect recursion to avoid infinite loops so it's safer than solutions in other answers.
PHP has a built-in method for this purpose, called count(). If passed without any additional parameters, count() returns the number of array keys on the first level. But, if you pass a second parameter to the count method count( $schema, true ), then the result will be the total number of keys in the multi-dimensional array. The response marked as correct only iterates first and second level arrays, if you have a third child in that array, it will not return the correct answer.
This could be written as a recursive function, if you really want to write your own count() method, though.
Transferred from comment below answer:
Basically, as you're adding the count_r of that array to the current level, you don't need to factor in the count in the second argument - you'd basically be adding it twice. You need the "1" in there, however, to count the array itself. If you'd want to count just the elements and not the arrays, you would just make the "1" a "0".
$schema = array(
'div' => array(
'class' => 'lines',
'div' => array(
'span' => array(
'key' => 'Product Name'
),
'val' => 'Soap'
),
'layer' => array(
'span' => array(
'key' => 'Product Name'
),
'val' => 'Ball'
)
)
);
function count_r($array, $i = 0){
foreach($array as $k){
if(is_array($k)){ $i += count_r($k, 1); }
else{ $i++; }
}
return $i;
}
echo count_r($schema);
This is tested and works correctly.
your function could be simple as
function count_r($array, $i = 0){
foreach($array as $k){
$i++;
if(is_array($k)){
$i += count_r($k);
}
}
return $i;
}
I have altered you code.. Please check it. It is working fine.
$schema = array(
'div' => array(
'class' => 'lines',
'div' => array(
'span' => array(
'key' => 'Product Name'
),
'val' => 'Soap'
),
'layer' => array(
'span' => array(
'key' => 'Product Name'
),
'val' => 'Ball'
)
)
);
function count_r($array){
foreach($array as $k){
if(is_array($k)){
$i += count_r($k);
}
else{
$i++;
}
}
return $i;
}
echo count_r($schema);
If you want to count specific keys/values you can use the built-in array_walk_recursive with a closure function.
$schema = array(
'div' => array(
'class' => 'lines',
'div' => array(
'span' => array(
'key' => 'Product Name'
),
'val' => 'Soap'
),
'layer' => array(
'span' => array(
'key' => 'Product Name'
),
'val' => 'Ball'
)
)
);
$elements = 0;
array_walk_recursive($schema, function($value, $key) use (&$elements) {
if (strstr($value, 'Product')) $elements++;
});
print $elements; // 2
/*
Values
lines
Product Name
Soap
Product Name
Ball
Keys
class
key
val
key
val
*/
count($array, COUNT_RECURSIVE)-count($array)

Conditionally adding item to multidimensional array

I have been looking how to do this and am a bit stumped.
My array is as follows:
$returndata->setup_array = array(
'General' => array(
'Main Details' => 'setup/maindets',
'Directories' => 'directories',
'Extension Allocation' => 'xtnallo',
'List Holidays' => 'setup/holidays',
'List Group VM' => 'groupvm',
'Conference Rooms' => 'confroom'
),
'Offices' => array(
'List Offices' => 'iptoffices'
),
'Users' => array(
'List Users' => 'iptusers'
),
'Phones' => array(
'List Phones' => 'iptphones'
),
);
However I have 1 item that on a certain condition(triggered by the users session) that needs to be added to the listin the general array. The section being 'View Details => setup/viewdetails'. I have tried array push (probably incorrectly) but this adds the item as another array at the end under the main array.
I want/need it to work like this:
$returndata->setup_array = array(
'General' => array(
$viewdets
'Main Details' => 'setup/maindets',
'Directories' => 'directories',
'Extension Allocation' => 'xtnallo',
'List Holidays' => 'setup/holidays',
'List Group VM' => 'groupvm',
'Conference Rooms' => 'confroom'
),
'Offices' => array(
'List Offices' => 'iptoffices'
),
'Users' => array(
'List Users' => 'iptusers'
),
'Phones' => array(
'List Phones' => 'iptphones'
),
);
$viewdets = "'View Details' => 'setup/viewdetails'";
and still be interpreted as a functioning array for use as a menu.
$returndata->setup_array['General']['View Details'] = 'setup/viewdetails'
Cheers Rick!
You can use ArrayObject to have the array as a reference:
$a = new ArrayObject();
$b = array(
"a" => $a
);
$a[] = "foo";
print_r($b);
What did you try calling array_push() on? Have you tried
array_push($returndata->setup_array['General'], $viewdets);
You would need to add the variable to the specific depth of the array you wanted it to be present. check out array_push here, there's also a short language syntax that avoids the function call:
$returndata->setup_array['General'][] = $viewdets;

How to build multi dimensional array for store this?

I want to store information like below with a key like key = activity window then other info under it, then another key etc..
key: 'activity window'
name: 'Recent Activity'
iconCls: 'activity'
module: 'activity-win'
any idea how to put this into a multi dimensional array?
$data = array(
'activity window' => array(
'name' => 'Recent Activity',
'iconCls' => 'activity',
'module' => 'activity-win'
)
);
Is this what you're looking for, or have I completely misunderstood your question?
Like this:
$myArray = array(
'activity window' => array(
'name' => 'Recent Activity',
'iconCls' => 'activity',
'module' => 'activity-win',
),
array(
...
),
);
You can also add on to the array:
$myArray['new key'] = array(
'name' => 'New Name',
'module' => 'New Module',
);

Categories