I am struggling with a data structure in PHP. I'm trying to use array_merge_recursive to condense an array by like keys and then grab all values instead of having them overwritten. This is why I chose array_merge_recursive instead of array_merge.
My array is something similar to:
Array
(
[0] => Array
(
[App] => APP1
[Type] => DB
)
[1] => Array
(
[App] => APP1
[Type] => WEBSITE
)
[2] => Array
(
[App] => APP2
[Type] => IOS
)
)
I was expecting array_merge_recursive to combine like keys and then group the other elements into arrays however this is not the behavior I am seeing.
I am hoping to get an array like the following:
Array
(
[0] => Array
(
[App] => APP1
[Type] => Array
(
[0] => DB
[1] => WEBSITE
)
)
[1] => Array
(
[App] => APP2
[Type] => IOS
)
)
array_merge_recursive() does not do what you think it does. You are looking for a function that restructures an array based on specific rules that are helpful to you and as such there isn't a builtin php function for that. I.e. How would PHP know that you wanted to new array to be structured by APP rather TYPE. Assuming your array is always that simple, the easiest version of the function you want looks something like this:
function sortByApp($array){
$result = array();
foreach($array as $row){
if(!isset( $result[ $row['APP'] ] ) {
$result[ $row['APP'] ] = array(
'APP' => $row['APP'],
'TYPE' => array( $row['TYPE'] )
);
}else{
$result[ $row['APP'] ]['TYPE'] = array_merge( $result[ $row['APP'] ]['TYPE'], array($row['TYPE']) );
}
}
$result = array_values($result); //All this does is remove the keys from the top array, it isn't really necessary but will make the output more closely match what you posted.
return $result
}
Note, in this solution, the value of the TYPE key in every APP will always be an array. This makes handling the data later easier in my opinion since you don't have to worry about checking for a string vs an array.
Related
I am using aws redis cache for quicker results instead of saving in db.
With this method
$result = $client->listTagsForResource([
'ResourceName' => '<string>', // REQUIRED
]);
Now it gives me result in given format.
Array
(
[0] => Array
(
[Key] => key1
[Value] => string1
)
[1] => Array
(
[Key] => status
[Value] => 1
)
)
I am unable to find a function in amazon docs which can give me direct results, so I decided to search in array , but finding in very large array with loops cost me in terms of time. So is there a way to convert it in following
Array
(
[key1] => string1,
[status] => 1
)
So I can directly access array index by using $array['key1']
You can try something like this to create new array:
$newArray = array_combine(
array_column($array, 'Key'),
array_column($array, 'Value')
);
echo $newArray['status'];
I have the following array, since i converted the string i got back from a SOAP call to an array:
Array
(
[soapenvBody] => Array
(
[queryRequestsResponse] => Array
(
[result] => Array
(
[0] => Array
(
[BCRcustomId] => REQ16569
[BCRexternalId] => Array
(
)
[BCRrecordId] => a035700001CM60kAAD
[BCRrequestId] => a1J5700000857EYEAY
)
[1] => Array
(
[BCRcustomId] => SRQ100784
[BCRexternalId] => Array
(
)
[BCRrecordId] => a033E000001PxfAQAS
[BCRrequestId] => a1J3E0000000GSaUAM
)
)
)
)
)
I am trying to retrieve the BCRrecordId, since I need that item to make another SOAP call. I tried the following
function getID($array) {
return $array['BCRcustomId'];
}
//
$arr = array_map('getID', $array );
print_r($arr);
Now i get an error back on this saying it doesnt find it.
Undefined index: BCRcustomId in
index.php on line 97
[soapenvBody] => )Array (
My assumption is that it doenst go lower than 1 level in the array. Now i am not familair with these kinds of arrays, how would I solve this? By multiple for each loops? Or is there another way to retrieve these items
If $array is the whole response, you need to pass only result part of it:
$arr = array_map('getID', $array['soapenvBody']['queryRequestsResponse']['result']);
I have a complex multi-dimensional array that looks something like
[name] => Marko Polo
[description] => New application
[number] => ABCD1234
[loans] => Array
(
[0] => Array
(
[id] => 123
[application_id] => 456
[loan_fees] => Array
(
)
[loan_parts] => Array
(
[0] => Array
(
[id] => 987
[loan_id] => 123
[product_id] => 49788
[product] => Array
(
[id] => 49788
[lender] => MAC
...
I need to create an efficient way of traversing this array and, for example having a set of rules to filter/modify the data.
For example, in the array there is [lender] => MAC, I want to have something like
loans.loan_parts.product.lender.MAC = 'Macquarie'
This would be in a config of sorts such that if the data array changed, it would be simply a matter of changing that dot notation to point to the new location of the lender value.
Using this, I need to filter the lender and modify it to be Macquarie instead of Mac.
I know that a big no-no these days is using too many foreach loops and I've looked into Collections, but because the inner arrays are not named, I don't believe Collections is possible.
As I say, I'd like to avoid the situation of
foreach
foreach
if (is_array())
foreach
eeewww!
How can I execute this in the most efficient manner due to the possible large size of the array and its complexity.
You can use array_walk_recursive with callback that will change behavior according to key of array.
<?php
//can pass variable by reference to change array in function
function handleMAC(&$item, $key)
{
if($key == 'lender'){
$item['MAC'] = 'your value';
}
}
array_walk_recursive($array, 'handleMAC');
?>
I have the follow array:
$arrIni["ENV"]="US";
$arrIni["sap_db_server"] = "192.xxx.x.xx";
$arrIni["local_db_server"] = "localhost";
$arrIni["local_db_username"] = "root";
//Default settings
$arrIni["arrEnvSettings"]["UserTypeID"]=4;
$arrIni["arrEnvSettings"]["LocalizationID"]=1;
$arrIni["arrEnvSettings"]["LangLabels"] = array();
$arrIni["arrEnvSettings"]["pages"]["st1"]="st1.php";
$arrIni["arrEnvSettings"]["pages"]["st2"]="st2.php";
$arrIni["arrEnvSettings"]["pages"]["st3"]="st3.php";
And I want to merge with this one:
$setParam["arrEnvSettings"]["pages"]["st3"]="st3_V2.php";
This is what I am doing:
echo "<pre>";
print_r(array_merge($arrIni,$setParam));
echo "</pre>";
And this is what I am getting:
Array
(
[ENV] => US
[sap_db_server] => 192.xxx.x.xx
[local_db_server] => localhost
[local_db_username] => root
[arrEnvSettings] => Array
(
[pages] => Array
(
[st3] => st3_V2.php
)
)
)
In the php doc about merge, this is the comment " ...If the input arrays have the same string keys, then the later value for that key will overwrite the previous one. ..."
So in this way, I suppose to get this output instead of the last one:
Array
(
[ENV] => US
[sap_db_server] => 192.xxx.x.xx
[local_db_server] => localhost
[local_db_username] => root
[arrEnvSettings] => Array
(
[UserTypeID] => 4
[LocalizationID] => 1
[LangLabels] => Array
(
)
[pages] => Array
(
[st1] => st1.php
[st2] => st2.php
[st3] => st3_V2.php
)
)
)
I do not understand why $setParam["arrEnvSettings"]["pages"]["st3"] is overriding the entire $arrIni["arrEnvSettings"].
Note:
If I use array_merge_recursive($arrIni,$setParam)) I will have the follow result but it is not what I want.
Array
(
[ENV] => US
[sap_db_server] => 192.xxx.x.xx
[local_db_server] => localhost
[local_db_username] => root
[arrEnvSettings] => Array
(
[UserTypeID] => 4
[LocalizationID] => 1
[LangLabels] => Array
(
)
[pages] => Array
(
[st1] => st1.php
[st2] => st2.php
[st3] => Array
(
[0] => st3.php
[1] => st3_V2.php
)
)
)
)
Is there a way to do this without iterate over the array? Only using merging? What am I doing wrong?
This should do the trick:
array_replace_recursive($arrIni,$setParam);
If you want to merge a given value, use this:
$arrIni["arrEnvSettings"]["pages"]["st3"] = $setParam["arrEnvSettings"]["pages"]["st3"];
But the way you're doing it is merging two arrays, not simply setting the value within an array. There's a gigantic difference between those two methods.
Otherwise, yes you will need to iteratively merge the arrays.
what you need is array_replace_recursive
print_r(array_replace_recursive($arrIni,$setParam));
didnt see the submitted answer..Felippe Duarte has given it already.....
I'm trying to figure out the correct function in PHP to sort a multidimensional array. I considered doing a foreach and then using ksort (this didn't work). I think it might be useful to note that the secondary keys (the numeric ones) are "manually" set (instead of using array_push since the first key in that scenario would be 0 instead of 1).
This is for a single instance so I don't need a class for this or anything super-special, I'm interested in the correct-context function in PHP to make this bit of code more performance oriented (as well as to figure out what I'm doing wrong).
Note I want to keep the PRIMARY keys (e,g, Main and Promotional) their current order.
The unsorted array...
Array
(
[Main] => Array
(
[3] => Main2
[2] => Content
[1] => Main1
)
[Promotional] => Array
(
[3] => Promotional1
[2] => Content
[1] => Promotional2
)
)
The desired outcome (sorting by second-level key)...
Array
(
[Main] => Array
(
[1] => Main1
[2] => Content
[3] => Main2
)
[Promotional] => Array
(
[1] => Promotional2
[2] => Content
[3] => Promotional1
)
)
You may try:
foreach($array as $key => $data) {
ksort($data);
$array[$key] = $data;
}
You could also try this:
foreach($array as $key => &$data) {
ksort($data);
}
the ampersand before the $data variable indicates that the $data variable is a pointer, and any changes to that variable will cascade back to the original configuration.