how to convert string to array? - php

Please, help solve the problem. I have a string like this:
[MoveNode(node='/html/head/meta[6]', target='/html/head[1]', position=22), MoveNode(node='/html/body/div[1]/main/div[1]/div/div/div/div/div[2]/ul/li[1]/a[1]', target='/html/head[1]', position=15), RenameNode(node='/html/head/a[1]', tag='meta'), InsertAttrib(node='/html/head/meta[6]', name='content', value='text text text text (text text), text'), InsertAttrib(node='/html/head/meta[6]', name='name', value='description'), DeleteAttrib(node='/html/head/meta[6]', name='href'), DeleteAttrib(node='/html/head/meta[6]', name='title'), UpdateTextIn(node='/html/head/meta[6]', text=None), MoveNode(node='/html/body/div[1]/main/footer/ul/li[2]/a[1]', target='/html/head[1]', position=16), RenameNode(node='/html/head/a[1]', tag='meta'), DeleteNode(node='/html/body/div[1]/main/div[1]/div/header/div/div/div[2]/div/h6[1]'), DeleteNode(node='/html/body/div[1]/main/div[1]/div/header/div/div/div[2]/div[1]')]
I need to convert this string to such an array. How to do it?
Array
(
[MoveNode_1] => Array
(
[node] => /html/head/meta[6]
[target] => /html/head[1]
[position] => 22
)
...
[InsertAttrib_4] => Array
(
[node] => /html/head/meta[6]
[name] => content
[value] => text text text text (text text), text
)
[InsertAttrib_5] => Array
(
[node] => /html/head/meta[6]
[name] => name
[value] => description
)
...
[MoveNode_9] => Array
(
[node] => /html/body/div[1]/main/footer/ul/li[2]/a[1]
[target] => /html/head[1]
[position] => 16
)
...
)
Tried to solve like this
$str = '....';
$arr0 = explode("), ", $str);
$arr2 = [];
$i = 1;
foreach ($arr0 AS $arr1) {
$arrs = explode("(", $arr1);
parse_str(str_replace(['\'', ', '], ['', '&'], $arrs[1]), $output);
$arr2[$arrs[0] . "_" . $i] = $output;
$i++;
}
print_r($arr2);
But because of the brackets inside the text, the array is formed incorrectly

You can use a combination of preg_match_all and array_map to extract the function names, node strings, and key-value pairs from the string.
$text = '[MoveNode(node=\'/html/head/meta[6]\', target=\'/html/head[1]\', position=22), MoveNode(node=\'/html/body/div[1]/main/div[1]/div/div/div/div/div[2]/ul/li[1]/a[1]\', target=\'/html/head[1]\', position=15), RenameNode(node=\'/html/head/a[1]\', tag=\'meta\'), InsertAttrib(node=\'/html/head/meta[6]\', name=\'content\', value=\'text text text text (text text), text\'), InsertAttrib(node=\'/html/head/meta[6]\', name=\'name\', value=\'description\'), DeleteAttrib(node=\'/html/head/meta[6]\', name=\'href\'), DeleteAttrib(node=\'/html/head/meta[6]\', name=\'title\'), UpdateTextIn(node=\'/html/head/meta[6]\', text=None), MoveNode(node=\'/html/body/div[1]/main/footer/ul/li[2]/a[1]\', target=\'/html/head[1]\', position=16), RenameNode(node=\'/html/head/a[1]\', tag=\'meta\'), DeleteNode(node=\'/html/body/div[1]/main/div[1]/div/header/div/div/div[2]/div/h6[1]\'), DeleteNode(node=\'/html/body/div[1]/main/div[1]/div/header/div/div/div[2]/div[1]\')]';
$str = preg_replace_callback("/(?<!\\\)'.*?(?<!\\\)'/s", function ($m) {
return str_replace(['(', ')', ','], ['&lpar;‎', '&rpar;‏', '‚'], $m[0]);
}, $text);
preg_match_all('/([\w]+)\(([^)]+)\)/', $str, $matches);
$functions = $matches[1];
$nodes = $matches[2];
$result = array_map(function ($function, $node) {
preg_match_all('/(\w+)=([^,]+)/', $node, $node_matches);
$keys = $node_matches[1];
$values = $node_matches[2];
return [$function => array_combine($keys, $values)];
}, $functions, $nodes);
echo "<pre>";
print_r($result);
exit;
the resulted array be like
Array
(
[0] => Array
(
[MoveNode] => Array
(
[node] => '/html/head/meta[6]'
[target] => '/html/head[1]'
[position] => 22
)
)
[1] => Array
(
[MoveNode] => Array
(
[node] => '/html/body/div[1]/main/div[1]/div/div/div/div/div[2]/ul/li[1]/a[1]'
[target] => '/html/head[1]'
[position] => 15
)
)
[2] => Array
(
[RenameNode] => Array
(
[node] => '/html/head/a[1]'
[tag] => 'meta'
)
)
[3] => Array
(
[InsertAttrib] => Array
(
[node] => '/html/head/meta[6]'
[name] => 'content'
[value] => 'text text text text (text text), text'
)
)
[4] => Array
(
[InsertAttrib] => Array
(
[node] => '/html/head/meta[6]'
[name] => 'name'
[value] => 'description'
)
)
[5] => Array
(
[DeleteAttrib] => Array
(
[node] => '/html/head/meta[6]'
[name] => 'href'
)
)
[6] => Array
(
[DeleteAttrib] => Array
(
[node] => '/html/head/meta[6]'
[name] => 'title'
)
)
[7] => Array
(
[UpdateTextIn] => Array
(
[node] => '/html/head/meta[6]'
[text] => None
)
)
[8] => Array
(
[MoveNode] => Array
(
[node] => '/html/body/div[1]/main/footer/ul/li[2]/a[1]'
[target] => '/html/head[1]'
[position] => 16
)
)
[9] => Array
(
[RenameNode] => Array
(
[node] => '/html/head/a[1]'
[tag] => 'meta'
)
)
[10] => Array
(
[DeleteNode] => Array
(
[node] => '/html/body/div[1]/main/div[1]/div/header/div/div/div[2]/div/h6[1]'
)
)
[11] => Array
(
[DeleteNode] => Array
(
[node] => '/html/body/div[1]/main/div[1]/div/header/div/div/div[2]/div[1]'
)
)
)

Related

Get Array in foreach loop from string

I have an Array of Strings, each String that exist in Advanced Custom Fields groups should be returned in foreach loop. Final results should be a single array of all values.
$lubuvna_groups = acf_get_field_groups();
$ArrayDiffs = array_diff($resultsFilesKey, $resultsKey);
foreach($ArrayDiffs as $ArrayDiff) {
$resultsFileToImports[] = $ArrayDiff;
}
//$keysToImports = implode(", ",$resultsFileToImports);
$keysToImports = 'group_lubuvna_contact, group_lubuvna_subscriber';
foreach($resultsFileToImports as $resultsFileToImportsKey) {
$keysToImports_filtered = array_filter($lubuvna_groups, function($el) use ($keysToImports) {
return ( strpos($el['key'], $keysToImports) !== false );
});
}
The above code returns only if one string exists in $keysToImports. Once there are more than one value it doesn't work. I am sure i am missing something, but can't find any solution in here!
It shows me empty Array:
Array ( )
Maybe there is a different way how to get the arrays without strpos?
Final Array should looks like following:
Array ( [0] => Array ( [ID] => 0 [key] => group_lubuvna_contact [title] => ACF Fields [fields] => Array ( ) [location] => Array ( [0] => Array ( [0] => Array ( [param] => post_type [operator] => == [value] => page ) ) ) [menu_order] => 0 [position] => normal [style] => default [label_placement] => top [instruction_placement] => label [hide_on_screen] => [active] => 1 [description] => [local] => json [modified] => 1592781382 [_valid] => 1 ) [1] => Array ( [ID] => 0 [key] => group_lubuvna_subscriber [title] => Lubuvna - Subscriber Fields [fields] => Array ( ) [location] => Array ( [0] => Array ( [0] => Array ( [param] => post_type [operator] => == [value] => post ) ) [1] => Array ( [0] => Array ( [param] => post_type [operator] => == [value] => page ) ) [2] => Array ( [0] => Array ( [param] => post_type [operator] => == [value] => lubuvna_subscriber ) ) ) [menu_order] => 0 [position] => normal [style] => default [label_placement] => top [instruction_placement] => label [hide_on_screen] => [active] => 1 [description] => [local] => json [modified] => 1592781369 [_valid] => 1 ) )
Try changing:
$keysToImports = 'group_lubuvna_contact', 'group_lubuvna_subscriber';
// then return
return ( strpos($el['key'], $keysToImports) !== false );
to
$keysToImports = ['group_lubuvna_contact', 'group_lubuvna_subscriber'];
// then return
return in_array($el['key'], $keysToImports);
Full code update:
$lubuvna_groups = acf_get_field_groups();
$ArrayDiffs = array_diff($resultsFilesKey, $resultsKey);
foreach($ArrayDiffs as $ArrayDiff) {
$resultsFileToImports[] = $ArrayDiff;
}
$keysToImports = ['group_lubuvna_contact', 'group_lubuvna_subscriber'];
foreach($resultsFileToImports as $resultsFileToImportsKey) {
$keysToImports_filtered = array_filter($lubuvna_groups, function($el) use ($keysToImports) {
return in_array($el['key'], $keysToImports);
});
}

how can I find value in sub multidimensional array?

I have this array:
Array ( [0] => Array ( [asset] => track [path] => media/promenade_web/AUDIO/promenade-arkadiev.mp3 [file_name] => promenade-arkadiev [permission_audio_play_synchronization] => Array ( [synchronization] => Array ( [constraint] => Array ( [numberOfMeasures] => Array ( [startMeasure] => 1 [number] => 10 ) [qualityOfResource] => medium ) [requirement] => Array ( ) [condition] => Array ( ) ) [play] => Array ( [constraint] => Array ( [numberOfMeasures] => Array ( [startMeasure] => 1 [number] => 10 ) [qualityOfResource] => medium [spatial] => iso3166:CH,IT [count] => 10 [datetime] => Array ( [start] => 2017-08-16 [end] => 2017-10-20 ) [accumulated] => P30D [format] => mp3,wav ) [requirement] => Array ( ) [condition] => Array ( ) ) ) ) [1] => Array ( [asset] => track [path] => media/promenade_web/AUDIO/promenade-arkadiev_lo.mp3 [file_name] => promenade-arkadiev_lo [permission_audio_play_synchronization2] => Array ( [play] => Array ( [constraint] => Array ( [numberOfMeasures] => Array ( [startMeasure] => 1 [number] => 10 ) [qualityOfResource] => medium [spatial] => iso3166:CH,IT [count] => 10 [datetime] => Array ( [start] => 2017-08-16 [end] => 2017-10-20 ) [accumulated] => P30D [format] => mp3,wav ) [requirement] => Array ( [prepay] => Array ( [amount] => 0.99 [currency] => EUR ) ) [condition] => Array ( ) ) ) ) )
How can I find a value with foreach, regardless of the number of subarrays?
I've tried with this code, but it doesn't work:
function recursive_array_search($needle, $haystack, $currentKey = '') {
foreach($haystack as $key=>$value) {
if (is_array($value)) {
$nextKey = recursive_array_search($needle,$value, $currentKey . '[' . $key . ']');
if ($nextKey) {
return $nextKey;
}
}
else if($value==$needle) {
return is_numeric($key) ? $currentKey . '[' .$key . ']' : $currentKey;
}
}
return false;
}
I always use following on multi dimensional array
$arr = array(array('id'=>1,'name'=>'nilesh'),array('id'=>2,'name'=>'ajay'));
echo "<pre>";
print_r($arr[array_search('nilesh', array_column($arr,'name'))]);
echo "</pre>";

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);

Order array multi-dimensional

I have an array that looks like this:
$cars = array (
array(
'a' => 'audi',
'b' => 'a4'),
array(
'a' => 'peugeot',
'b' => '306'),
array(
'a' => 'audi',
'b' => 'a4'),
array(
'a' => 'audi',
'b' => 'a5'),
array(
'a' => 'peugeot',
'b' => '106'),
array(
'a' => 'peugeot',
'b' => '106'),
);
I need to order arrays like this to (id is the same as name):
name => audi
id=> audi
data => a4 => 2
a5 => 1
name => peugeot
id=> peugeot
data => 306 => 1
106 => 2
So the car brands need to be grouped an the car types counted.
I already have this code; but that is only for the group part and the count part is missing.
function mergeAndOrder($data){
// set group arrays
$i = 0; $group1 = array();
// loop trough array
$array = array(); $array2 = array();
if($data != null){
foreach($data AS $row){
// search and order level1
$search = array_search($row->a,$group1);
// this object is not found
if(is_int($search) == false){
$group1[$i] = $row->a;
$array[$i]['id'] = $row->a;
$array[$i]['name'] = $row->a;
$array[$i]['data'] = array();
$i++;
}
}
}
return $array;
}
Does somebody know an solution for this case? Thanks!
--- INPUT (part of) ---
a = lease company in this case
Array
(
[0] => stdClass Object
(
[b] => AUDI
[a] => LPN
)
[1] => stdClass Object
(
[b] => AUDI
[a] => LPN
)
[2] => stdClass Object
(
[b] => AUDI
[a] => LPN
)
[3] => stdClass Object
(
[b] => AUDI
[a] => LPN
)
--- OUTPUT (part of) ---
Array
(
[0] => Array
(
[id] => LPN
[name] => LPN
[data] => Array
(
)
)
[1] => Array
(
[id] => ARV
[name] => ARV
[data] => Array
(
)
)
[2] => Array
(
[id] => ARVB
[name] => ARVB
[data] => Array
(
)
)
[3] => Array
(
[id] => LPD
[name] => LPD
[data] => Array
(
)
)
)
Array
(
[0] => Array
(
[id] => LPN
[name] => LPN
[data] => Array
(
)
)
[1] => Array
(
[id] => ARV
[name] => ARV
[data] => Array
(
)
)
[2] => Array
(
[id] => ARVB
[name] => ARVB
[data] => Array
(
)
)
If I understand your question correctly, this should do what you want.
function mergeAndOrder ($data) {
$output = array();
foreach ($data as $item) {
$id = $item->a;
$value = $item->b;
if (!array_key_exists($id, $output)) {
$output[$id] = array('id' => $id, 'name' => $id, 'data' => array());
}
if (!array_key_exists($value, $output[$id]['data'])) {
$output[$id]['data'][$value] = 0;
}
$output[$id]['data'][$value]++;
}
// Order by name element
uasort($output, function ($a, $b) {
return strcasecmp($a['name'], $b['name']);
});
return $output;
}
Output:
Array
(
[audi] => Array
(
[id] => audi
[name] => audi
[data] => Array
(
[a4] => 2
[a5] => 1
)
)
[peugeot] => Array
(
[id] => peugeot
[name] => peugeot
[data] => Array
(
[306] => 1
[106] => 2
)
)
)

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