I have a large array converted from a JSON structure with an unknown number of elements and sublevels.
Something like:
$marr = array
(
"Order" => array
(
"Details" => array
(
"Document" => array
(
"Number" => "1585636772",
"Date" => "2014-12-31"
),
"Delivery" => array
(
"Date" => "2015-01-02",
"TrackingCode" => "5703",
"Name" => "Example Name",
"Address" => "Example Address"
)
)
)
);
And on the other hand, I have an array of items I need to compare and find out if they are in the array above. This "indexer" will always mirror the same structure above (it's generated before the comparison step) because I thought that would help me ensure a proper comparison in an easier way.
Something like:
$indexer = array
(
"Order" => array
(
"Details" => array
(
"Document" => array
(
"Date" => "variable_name_1"
),
"Delivery" => array
(
"Date" => "variable_name_2"
)
)
)
);
I'm not entirely sure how best to compare these. I have looked into array_walk_recursive() which only returns the leaf values and I have tried to write my own attempts at a basic recursive function that would perform a foreach() which would then try to do something like:
if( isset($marr["Order"]["Details"]["Document"]["Date"]) )
{
$store[ $indexer["Order"]["Details"]["Document"]["Date"] ] = $marr["Order"]["Details"]["Document"]["Date"];
}
So that at the end I would have a basic array that stored all values found on $marr under an alias that was listed on $indexer. Like this:
$store["variable_name_1"] = "2014-12-31";
$store["variable_name_2"] = "2015-01-02";
This has been a headache for two days now and I can't seem to figure out the best way to go through this. I'm trying to walk through $indexer to reach its ending, obtain the "variable name", and then compare with $marr to store its data, but I always seem to lose the parent nodes of $indexer while trying to do this recursively. I would appreciate any advice at all.
You could use this recursive function:
function storeFromIndex($marr, $indexer) {
if (!is_array($indexer)) {
return array($indexer => $marr);
}
$store = [];
foreach($indexer as $key => $subindexer) {
$store = array_merge($store, storeFromIndex($marr[$key], $subindexer));
}
return $store;
}
And then call it like this:
$store = storeFromIndex($marr, $indexer);
With the example data given, $store will be:
array (
'variable_name_1' => '2014-12-31',
'variable_name_2' => '2015-01-02',
)
Here I would like to suggest do not maintain indexer, you can use iterator and create new array using associated keys.
For example have a look on below solution:
$array = array
(
"Order" => array
(
"Details" => array
(
"Document" => array
(
"Number" => "1585636772",
"Date" => "2014-12-31"
),
"Delivery" => array
(
"Date" => "2015-01-02",
"TrackingCode" => "5703",
"Name" => "Example Name",
"Address" => "Example Address"
)
)
)
);
$new_array = array();
$iterator = new RecursiveIteratorIterator(new RecursiveArrayIterator($array));
foreach ($iterator as $key => $value) {
$keys = array();
$keys[] = $key;
for ($i = $iterator->getDepth() - 1; $i >= 0; $i--) {
$keys[] = $iterator->getSubIterator($i)->key();
}
$key_paths = array_reverse($keys);
$new_array[implode('_', $key_paths)] = $value;
}
print_r($array);
print_r($new_array);
Output:
Array
(
[Order] => Array
(
[Details] => Array
(
[Document] => Array
(
[Number] => 1585636772
[Date] => 2014-12-31
)
[Delivery] => Array
(
[Date] => 2015-01-02
[TrackingCode] => 5703
[Name] => Example Name
[Address] => Example Address
)
)
)
)
Array
(
[Order_Details_Document_Number] => 1585636772
[Order_Details_Document_Date] => 2014-12-31
[Order_Details_Delivery_Date] => 2015-01-02
[Order_Details_Delivery_TrackingCode] => 5703
[Order_Details_Delivery_Name] => Example Name
[Order_Details_Delivery_Address] => Example Address
)