traversing array, which can be of multiple depth - php

I have following array pattern.
Array
(
[0] => Array
(
[label] => 2011
[subtable] => Array
(
[0] => Array
(
[label] => 05
[subtable] => Array
(
[0] => Array
(
[label] => /hello-world.html
[url] => http://example.com/2011/05/hello-world.html
)
[1] => Array
(
[label] => /test-test-test.html
[url] => http://example.com/2011/05/test-test-test.html
)
)
)
[1] => Array
(
[label] => 04
[subtable] => Array
(
[0] => Array
(
[label] => /i-have-some-problem-with-gfc-updates.html
[url] => http://example.com/2011/04/i-have-some-problem-with-gfc-updates.html
)
[1] => Array
(
[label] => /testing-for-google-frineds-update.html
[url] => http://example.com/2011/04/testing-for-google-frineds-update.html
)
)
)
[2] => Array
(
[label] => /05
[url] => http://example.com/2011/05
)
[3] => Array
(
[label] => /04
[url] => http://example.com/2011/04
)
)
)
[1] => Array
(
[label] => /index
[url] => http://example.com/
)
)
I want to get "label" and "url" into another array like
array(
[0] = array([label] => a [url] => http://example.com/a/)
[1] = array([label] => b [url] => http://example.com/b/)
)
How can I achieve it using recursion, or by passing it to a function?

You may use array_walk_recursive for this:
$parsed_array = array();
function parse_array($item, $key) {
global $parsed_array;
if(is_array($item) && isset($item['url'])) {
$parsed_array[] = $item;
}
}
array_walk_recursive($your_array, 'parse_array');
Or you may implement it using a recursive function:
function parse_array($array) {
$result = array();
foreach($array as $item) {
if(isset($item['subtable'])) {
$result = array_merge($result, parse_array($item['subtable']));
}else{
$result[] = $item;
}
}
return $result;
}
$parsed_array = parse_array($your_array);

Related

Multidimensional arrays, remove the duplicated array in next array

My arrays result is like this one
Array
(
[0] => Array
(
[id] => Bank Transfer
[ec] => 1000
[accounts] => Array
(
[0] => Array
(
[name] => Account WD
[value] =>
)
[1] => Array
(
[name] => Keterangan
[value] =>
)
)
)
[1] => Array
(
[id] => Wired
[ec] => 1001
[accounts] => Array
(
[0] => Array
(
[name] => Account WD
[value] =>
)
[1] => Array
(
[name] => Keterangan
[value] =>
)
[2] => Array
(
[name] => Account ID
[value] =>
)
)
)
)
It's weird because 2nd array of accounts contains same value as first array.
[0] => Array
(
[name] => Account WD
[value] =>
)
[1] => Array
(
[name] => Keterangan
[value] =>
)
How to prevent this duplicated so the 2nd array of accounts will only show
[0] => Array
(
[name] => Account ID
[value] =>
)
Here's my code
$arr = $arr_pay = array();
foreach($site_payment as $key => $value){
if($value['status'] && $value['ec']>=1000){
$payment_data_cust = unserialize(crypts($value['auto_wd_data'],'d'));
foreach ($payment_data_cust as $ke => $va) {
$arr[] = array("name"=>$va,"value"=>'');
}
$spc[] = array(
"id"=>$value['id'],
"ec"=>$value['ec'],
"accounts"=>$arr
);
}
}
Array of $site_payment contains
[Bank Transfer] => Array
(
[id] => Bank Transfer
[ec] => 1000
[status] => 1
[auto_wd_data] => IjZRcWp1aGtzNmZHbjVPZTlkeStGZVNPaWdPY0lrZ0UyQnd6eFhxQUZoR1VEeU82TzVJZkdMelJrZzJKS3lxXC9yTm5meFBndFRlUDQ9Ig==
)
[Dana] => Array
(
[id] => Wired
[ec] => 1001
[status] => 1
[auto_wd_data] => IkNDek9IY1BtelVEeFFxZEtMc0hvalBkbVBRdENEZEJWakZoaFBJWkNBUk09Ig==
)
I want to show the auto_wd_data of $site_payments with different array so it's became the result, but not duplicating in each array
Please help me to solve the problem
Duplication is due to the $arr is not being reset
$arr_pay = array();
foreach($site_payment as $key => $value){
$arr = array(); // Resetting
if($value['status'] && $value['ec']>=1000){
$payment_data_cust = unserialize(crypts($value['auto_wd_data'],'d'));
foreach ($payment_data_cust as $ke => $va) {
$arr[] = array("name"=>$va,"value"=>'');
}
$spc[] = array(
"id"=>$value['id'],
"ec"=>$value['ec'],
"accounts"=>$arr
);
}
}

Combine some php sub-arrays, with condition

$routes array:
[admin/login] => Array
(
[0] => POST|AJAX
[1] => admin/login
[2] => admin/login
)
[admin/logout] => Array
(
[0] => POST
[1] => admin/logout
[2] => admin/logout
)
[admin/dashboard] => Array
(
[0] => GET
[1] => admin/dashboard
[2] => admin/dashboard
)
[admin/products] => Array
(
[0] => GET
[1] => admin/products/[:pag]
[2] => admin/products/all
)
[admin/products/add] => Array
(
[0] => GET
[1] => admin/product/add
[2] => admin/products/add
)
[admin/products/insert] => Array
(
[0] => POST
[1] => admin/product/insert
[2] => admin/products/insert
)
[admin/products/show] => Array
(
[0] => GET
[1] => admin/product/[i:id]
[2] => admin/products/show
)
[admin/products/edit] => Array
(
[0] => GET
[1] => admin/product/[i:id]/edit
[2] => admin/products/edit
)
[admin/products/update] => Array
(
[0] => POST
[1] => admin/product/update
[2] => admin/products/update
)
[admin/products/delete] => Array
(
[0] => POST
[1] => admin/product/delete
[2] => admin/products/delete
)
[admin/categories] => Array
(
[0] => GET
[1] => admin/categories
[2] => admin/categories/all
)
[admin/categories/add] => Array
(
[0] => GET
[1] => admin/category/add
[2] => admin/categories/add
)
[admin/categories/insert] => Array
(
[0] => POST
[1] => admin/category/insert
[2] => admin/categories/insert
)
[admin/categories/show] => Array
(
[0] => GET
[1] => admin/category/[i:id]
[2] => admin/categories/show
)
[admin/categories/edit] => Array
(
[0] => GET
[1] => admin/category/[i:id]/edit
[2] => admin/categories/edit
)
[admin/categories/update] => Array
(
[0] => POST
[1] => admin/category/update
[2] => admin/categories/update
)
[admin/categories/delete] => Array
(
[0] => POST
[1] => admin/category/delete
[2] => admin/categories/delete
)
[admin/api] => Array
(
[0] => GET
[1] => admin/api
[2] => admin/api/all
)
[admin/filter/sessions] => Array
(
[0] => POST|AJAX
[1] => admin/filter/sessions
[2] => admin/filters/sessions
)
This is $admin_routes array (build from $routes):
[login] => Array
(
[0] => admin/login
)
[logout] => Array
(
[0] => admin/logout
)
[dashboard] => Array
(
[0] => admin/dashboard
)
[products] => Array
(
[0] => admin/products
[1] => admin/products/add
[2] => admin/products/insert
[3] => admin/products/show
[4] => admin/products/edit
[5] => admin/products/update
[6] => admin/products/delete
)
[api] => Array
(
[0] => admin/api
)
[filter] => Array
(
[0] => admin/filter/sessions
)
[categories] => Array
(
[0] => admin/categories
[1] => admin/categories/add
[2] => admin/categories/insert
[3] => admin/categories/show
[4] => admin/categories/edit
[5] => admin/categories/update
[6] => admin/categories/delete
)
I need some help from you guys about $admin_routes.
I want to combine all sub-arrays from $admin_routes, from same area, which has only one element, in a new sub-array with key name formed from their key names.
Also i want the new sub-array to have same 'position' in line.
My imperfect solution:
// creating $admin_routes
$admin_routes = [];
foreach ($routes as $name => $route) {
if (preg_match('/^admin\/(.*)$/', $name))
$admin_routes[explode('/', $name)[1]][] = $name;
}
// imperfect solution for what i want
$single = false;
$waiting = [];
foreach ($admin_routes as $section => $routes) {
if (count($routes) == 1) { // remember all sub-arrays, with one single element, from same area
$single = true;
$waiting[$section] = $routes;
}
else if ($single) { // if found all sub-arrays, with one single element, from same area
$name = '';
$subarray = [];
foreach ($waiting as $section => $routes) {
// creating only one sub-array
$name .= ($section . ' ');
$subarray = array_merge($subarray, $routes);
unset($admin_routes[$section]);
}
// the problem is, sub-array it's added at the end of $admin_routes
// (not where sub-array's elements were before)
$admin_routes[$name] = $subarray;
$single = false;
$waiting = [];
}
}
The problem is, the new sub-arrays are placed at the end.
If you have any idea, please help me. Thx.
Using your actual result $admin_routes, you could loop through them and rebuild the desired array:
$real_routes = []; // The new array
$singles_key = ''; // The key for combined sub-arrays
$singles_routes = []; // The routes for combined sub-arrays
foreach ($admin_routes as $name => $r) {
/* If this route array has a single entry,
add its name and value to our temp vars */
if (count($r) === 1) {
$singles_key .= $name . ' ';
$singles_routes = array_merge($singles_routes, $r);
} else {
/* If then a route array has multiple value,
save the combined singles and then save this one */
if (!empty($singles_key)) {
$real_routes[trim($singles_key)] = $singles_routes;
$singles_key = '';
$singles_routes = [];
}
$real_routes[$name] = $r;
}
}
/* If the loop ends but the temp vars aren't empty,
save the lasts combined singles */
if (!empty($singles_key)) {
$real_routes[trim($singles_key)] = $singles_routes;
}
// Then to output:
echo '<pre>' . print_r($real_routes, true) . '</pre>';

Arrange an array recursively

I'm trying to arrange an array in levels. This is my array:
Array
(
[0] => Array(
[0] => Array(
[id] => 971249312[name] => Wolverine
)
[children] => Array(
[0] => Array(
[0] => Array(
[id] => 735327624[name] => Ciclop
)
[children] => Array()
)
)
)
[1] => Array(
[0] => Array(
[id] => 1926833684[name] => Gambit
)
[children] => Array()
)
[2] => Array(
[0] => Array(
[id] => 51194629[name] => Quicksilver
)
[children] => Array()
)
)
See that the first position of array has 3 elements - this must be the level 0. The first position of these elements must be the level 1. The children of these elements are the next level and so on.
I canĀ“t figure out how to arrange it.
the expected output:
Array
(
["level_1"] => Array
(
[0] => Array
(
[id] => 971249312
[name] => Wolverine
)
[1] => Array
(
[id] => 1926833684
[name] => Gambit
)
[2] => Array
(
[id] => 51194629
[name] => Quicksilver
)
)
["level_2"] => Array
(
[0] => Array
(
[id] => 735327624
[name] => Ciclop
)
)
)
Another recursive tree walk.
I scan the tree 'depth first' so I need to keep track of the current 'level'.
Demonstration at eval.in
Tree scan routine:
/**
* Recursive scan of the tree
*
* #node array Current Node to be processed
* #level integer Current depth of the tree
* output array reference to where to store the details
*
* #return void
*/
function scanNode($node, $level, &$output)
{
$outLevelIdx = 'level_'. $level;
foreach ($node as $idx => $info) {
$parent = current($info);
$output[$outLevelIdx][] = array('id' => $parent['id'], 'name' => $parent['name']);
if (!empty($info['children'])) { // go scan the children
scanNode($info['children'], $level + 1, $output);
}
}
}
Run the scan:
/*
* Output array in here - pass as a reference
*/
$output = array();
// scan the full tree
scanNode($source, 0, $output);
Sample output:
output
Array
(
[level_0] => Array
(
[0] => Array
(
[id] => 971249312
[name] => Wolverine
)
[1] => Array
(
[id] => 1926833684
[name] => Gambit
)
[2] => Array
(
[id] => 51194629
[name] => Quicksilver
)
)
[level_1] => Array
(
[0] => Array
(
[id] => 735327624
[name] => Ciclop
)
)
)
If your desired output is
Array
(
[0] => Array
(
[id] => 971249312
[name] => Wolverine
[children] => Array
(
)
)
[1] => Array
(
[id] => 971249312
[name] => Wolverine
[children] => Array
(
)
)
[2] => Array
(
[id] => 971249312
[name] => Wolverine
[children] => Array
(
)
)
)
Then your code should be
$newArray = [];
foreach ($givenArray as $key => $value) {
$newArray[$key]['id'] = $value[0]['id'];
$newArray[$key]['name'] = $value[0]['name'];
$newArray[$key]['children'] = $value['children'];
}
AS per your desired output
This function used to scan all the node and provide as per your requirment.
OUTPUT
$newArray = [];
myfunction($a, 0,$newArray);
function myfunction($loop, $level, &$newArray) {
$index = "level_".$level;
$i = 0;
foreach ($loop as $key => $value) {
foreach ($value as $key1 => $value1) {
if($key1 !== 'children'){
$newArray[$index][$i] = ['id' => $value1['id'], 'name' => $value1['name']];
$i++;
}
}
if (isset($value['children']) && !empty($value['children'])) {
myfunction($value['children'], $level + 1, $newArray);
}
}
}
print_r($newArray);exit;

Change key of multidimensional array

I have following array as response from db. I am trying to convert this database response into multidimensional array as per my requirement.
Array
(
[0] => Array
(
[0] => Array
(
[_id] => C10359
[AE] => Array
(
[0] => 89785
[1] => 89786
[2] => 89857
[3] => 89859
)
)
[1] => Array
(
[_id] => C10428
[AE] => Array
(
[0] => 50191
[1] => 50203
[2] => 50230
[3] => 50244
)
)
)
[1] => Array
(
[0] => Array
(
[_id] => C10350
[AE] => Array
(
[0] => 89785
[1] => 89786
[2] => 89857
[3] => 89859
)
)
[1] => Array
(
[_id] => C10430
[AE] => Array
(
[0] => 50191
[1] => 50203
[2] => 50230
[3] => 50244
)
)
)
)
Now I need to convert above array in following way.
Array
(
[0] => Array
(
[C10359] => Array
(
[0] => 89785
[1] => 89786
[2] => 89857
[3] => 89859
)
[C10428] => Array
(
[0] => 50191
[1] => 50203
[2] => 50230
[3] => 50244
)
)
[1] => Array
(
[C10350] => Array
(
[0] => 89785
[1] => 89786
[2] => 89857
[3] => 89859
)
[C10430] => Array
(
[0] => 50191
[1] => 50203
[2] => 50230
[3] => 50244
)
)
)
following is way i am trying
array_map(function($arr) {
return $arr[0] ;
},$panel_result);
But it is not working.
Kindly suggest how can I convert in required formate.
This should do the trick :
$arr = array(
array(
array(
'_id' => 'C10359',
'AE' => array
(
89785,
89786,
89857,
89859,
),
),
array(
'_id' => 'C10428',
'AE' => array
(
50191,
50203,
50230,
50244,
),
),
),
);
$output = array();
foreach ($arr as $levelK => $level) {
if(!isset($output[$levelK])){
$output[$levelK] = array();
}
foreach ($level as $subLevel) {
$id = $subLevel['_id'];
if (!isset($output[$levelK][$id])) {
$output[$levelK][$id] = array();
}
foreach ($subLevel['AE'] as $val) {
$output[$levelK][$id][] = $val;
}
}
}
Hope this helps.
Use array_column() and pass third param as the index key.
$reqArray = array();
foreach ($yourArray as $key => $innerArray) {
$reqArray[] = array_column($innerArray, 'AE', '_id');
}
OR
Use array map()
$reqArray = array_map(function($a){
return array_column($a, 'AE', '_id');
},$arr);

Find a value in nested associative array

I want to get the value of 'GUID' with the value of 'SamAccountName'. i.e. I only have the value pf 'SamAccountName' and I would like to get the value of 'GUID' for that part of the array.
Array
(
[0] => Array
(
[DistinguishedName] => CN=johnn#playgroundla,OU=playgroundla,OU=Hosting,DC=exch024,DC=domain,DC=local
[GUID] => 26d7c204-7db7-4601-8cd2-0dd0d3b37d97
[OriginatingServer] => dcprov024-CA-1.exch024.domain.local
[Name] => johnn#playgroundla
[HostingObjectType] => Array
(
[HostingObjectTypes] => Array
(
[0] => ActiveSync
[1] => MSExchange2007Mailbox
[2] => ActiveDirectoryUser
)
)
[HostingOwners] => Array
(
[HostingObjectOwners] => Array
(
[0] => MSExchange2007Mailboxes
[1] => ActiveDirectoryUsers
)
)
[Attributes] => Array
(
[Hidden] =>
[ReadOnly] =>
[SpecialAccess] =>
[Items] => Array
(
)
)
[DisplayName] => John Nolan
[SamAccountName] => johnn_playgroundla
[FullSamAccountName] => EXCH024\johnn_playgroundla
[UserPrincipalName] => johnn#playgroundla.com
[AccountExpires] =>
[Enabled] =>
[EnabledFeatures] => Array
(
[string] => Array
(
[0] => ActiveSync
[1] => MSExchangeMailboxes
[2] => ActiveDirectoryUsers
)
)
[LastLogonTimestamp] =>
)
[1] => Array
(
[DistinguishedName] => CN=csliney#playgroundla,OU=playgroundla,OU=Hosting,DC=exch024,DC=domain,DC=local
[GUID] => 71224be8-1b8b-46e7-97ef-2cd873bf9b7f
[OriginatingServer] => dcprov024-CA-1.exch024.domain.local
[Name] => csliney#playgroundla
[HostingObjectType] => Array
(
[HostingObjectTypes] => Array
(
[0] => ActiveSync
[1] => MSExchange2007Mailbox
[2] => ActiveDirectoryUser
)
)
[HostingOwners] => Array
(
[HostingObjectOwners] => Array
(
[0] => MSExchange2007Mailboxes
[1] => ActiveDirectoryUsers
)
)
[Attributes] => Array
(
[Hidden] =>
[ReadOnly] =>
[SpecialAccess] =>
[Items] => Array
(
)
)
[DisplayName] => Christopher Sliney
[SamAccountName] => csliney_playgroundla
[FullSamAccountName] => EXCH024\csliney_playgroundla
[UserPrincipalName] => csliney#playgroundla.com
[AccountExpires] =>
[Enabled] =>
[EnabledFeatures] => Array
(
[string] => Array
(
[0] => ActiveSync
[1] => MSExchangeMailboxes
[2] => ActiveDirectoryUsers
)
)
[LastLogonTimestamp] =>
)
[2] => Array
(
[DistinguishedName] => CN=lee#playgroundla,OU=playgroundla,OU=Hosting,DC=exch024,DC=domain,DC=local
[GUID] => b428b57f-4cd4-4243-a76a-f25f5ff3be97
[OriginatingServer] => dcprov024-CA-1.exch024.domain.local
[Name] => lee#playgroundla
[HostingObjectType] => Array
(
[HostingObjectTypes] => Array
(
[0] => MSExchange2007Mailbox
[1] => ActiveDirectoryUser
)
)
[HostingOwners] => Array
(
[HostingObjectOwners] => Array
(
[0] => MSExchange2007Mailboxes
[1] => ActiveDirectoryUsers
)
)
[Attributes] => Array
(
[Hidden] =>
[ReadOnly] =>
[SpecialAccess] =>
[Items] => Array
(
)
)
[DisplayName] => Lee Roderick
[SamAccountName] => lee_playgroundla
[FullSamAccountName] => EXCH024\lee_playgroundla
[UserPrincipalName] => lee#playgroundla.com
[AccountExpires] =>
[Enabled] =>
[EnabledFeatures] => Array
(
[string] => Array
(
[0] => MSExchangeMailboxes
[1] => ActiveDirectoryUsers
)
)
[LastLogonTimestamp] =>
)
[3] => Array
(
[DistinguishedName] => CN=theresa#playgroundla,OU=playgroundla,OU=Hosting,DC=exch024,DC=domain,DC=local
[GUID] => 4b2aee17-9e88-4de9-b95b-63a9877835a6
[OriginatingServer] => dcprov024-CA-1.exch024.domain.local
[Name] => theresa#playgroundla
[HostingObjectType] => Array
(
[HostingObjectTypes] => Array
(
[0] => ActiveSync
[1] => MSExchange2007Mailbox
[2] => ActiveDirectoryUser
)
)
[HostingOwners] => Array
(
[HostingObjectOwners] => Array
(
[0] => MSExchange2007Mailboxes
[1] => ActiveDirectoryUsers
)
)
[Attributes] => Array
(
[Hidden] =>
[ReadOnly] =>
[SpecialAccess] =>
[Items] => Array
(
)
)
[DisplayName] => Theresa Baker
[SamAccountName] => theresa_playgroundla
[FullSamAccountName] => EXCH024\theresa_playgroundla
[UserPrincipalName] => theresa#playgroundla.com
[AccountExpires] =>
[Enabled] =>
[EnabledFeatures] => Array
(
[string] => Array
(
[0] => ActiveSync
[1] => MSExchangeMailboxes
[2] => ActiveDirectoryUsers
)
)
[LastLogonTimestamp] =>
)
)
This was originally a stdClass object but I used json_decode(json_encode($obj), true) to convert to an associative array.
Sounds like you want to get the GUID portion for the value of 'SamAccountName'. Use a foreach loop:
function getGUID($san, $array) {
foreach($array as $a) {
if($a['SamAccountName'] == $san) {
return $a['GUID'];
}
}
return false;
}
$guid = getGUID("SamAccountNameHere", $yourArray);
You can use a simple loop to fetch it
$id = 0;
foreach($data as $item) {
if (isset($item['SamAccountName']) && 'accountName' == $item['SamAccountName']) {
$id = $item['GUID'];
break;
}
}
var_dump($id);
is this what you are looking for?
function findBySam($arrayList, $sam) {
foreach($arrayList as $array) {
if($array['SamAccountName'] == $sam) {
return $array;
}
}
return false;
}
Here is an example of a function that you could use. This assumes that there will be only one object with the SamAccountName that you supply in the array (it just uses the first one that it finds). It returns the GUID of the matching array and false if it cannot find an array with a matching SamAccountName.
function getGuidForSamAccountName($arr, $name) {
foreach ($arr as $elem) {
if ($elem['SamAccountName'] === $name) {
return $elem['GUID'];
}
}
return false; //No match found
}
You can use array_filter function of php:
http://php.net/manual/en/function.array-filter.php
example:
$GUID = "sample";
array_filter($array, "findElement");
function findElement($el) {
return $el["GUID"] == $_GLOBAL["GUID"];
}
Not a very elegant solution... but it should work.

Categories