From a nested array, I want to generate the 1D associative array which contains, for each leaf, its ascending keys concatenation.
Summary
Expected results example
1.1. Input
1.2. Output
Actual results example
1.1. Input
1.2. Output
Question
Minimal, Testable Executable Sources
4.1. Explanations
4.2. Sources & Execution
Expected results example
Input
The following nested array:
[
'key1' => 'foo',
'key2' => [
'key3' => [
0 => ['key4' => 'bar' ],
1 => ['key4' => 'azerty']
]
]
]
Output
The following 1D associative array (glue character for the concatenation of the keys: _):
[
'key1' => 'foo',
'key2_key3_0_key4' => 'bar',
'key2_key3_1_key4' => 'azerty'
]
Actual results example
Input
[
'etat' => 'bar',
'proposition_en_cours' => [
'fichiers' => [
0 => ['url_fichier' => 'foo' ],
1 => ['url_fichier' => 'bar']
]
]
]
Output
Array
(
[] => bar
[proposition_en_cours] => Array
(
[fichiers] => Array
(
[0] => Array
(
[url_fichier] => foo
)
[1] => Array
(
[url_fichier] => bar
)
)
)
[proposition_en_cours_fichiers] => Array
(
[0] => Array
(
[url_fichier] => foo
)
[1] => Array
(
[url_fichier] => bar
)
)
[proposition_en_cours_fichiers_0] => foo
[proposition_en_cours_fichiers_0_1] => bar
)
Question
As you can see, the array I get differs in all points from the expected one. I can't figure out why.
Minimal, Testable Executable Sources
Explanations
I initialize an array that must contain all the ascending keys for each leaf: $key_in_db_format = [];.
I iterate on the input array. For each element (leaf or subarray), I pop $key_in_db_format if, and only if, the current depth equals the last depth. If it's an array (i.e.: not a leaf): I add the key to $key_in_db_format. I set a value (the leaf) at the key that is the concatenation of the ascending keys.
Sources & Execution
First, define this array in an empty PHP script of your choice:
$values = [ 'etat' => 'bar', 'proposition_en_cours' => [ 'fichiers' => [ 0 => [ 'url_fichier' => 'foo' ], 1 => [ 'url_fichier' => 'bar' ] ] ] ];Then, copy/paste the following code and you will be able to execute it:
$values_to_insert_in_meta_table = []; $iterator = new \RecursiveIteratorIterator(new \RecursiveArrayIterator($values), \RecursiveIteratorIterator::SELF_FIRST); $last_depth = 0; $key_in_db_format = []; foreach ($iterator as $value_key_field => $value_value_field) { if($iterator->getDepth() == $last_depth) { array_pop($key_in_db_format); } if(is_array($value_value_field)) { array_push($key_in_db_format, $value_key_field); } else { $values_to_insert_in_meta_table[implode('_', $key_in_db_format)] = $value_value_field; } $last_depth = $iterator->getDepth(); } echo '<pre>'; print_r($values_to_insert_in_meta_table);
key2_key3_0_key4; instead you will getkey2_0_key3_0_key4. this is because if you don't provide a key, the default used will be zero-based integer. there would be no way to distinguish between the two. however you can use string integer for your explicit keys for your function to detect and include said keys, ie, ignore0,1, etc keys, include"0", "1", etc keys.