Example input as json
{
"user":{
"name":"Thomas",
"age":101
},
"shoppingcart":{
"products":{
"p1":"someprod",
"p2":"someprod2"
},
"valuta":"eur",
"coupon":null,
"something":[
"bla1",
"bla2"
]
}
}
Expected output
[
'user.name' => 'Thomas',
'user.age' => 101,
'shoppingcart.products.p1' => 'someprod',
...
'shoppingcart.something.1' => 'bla1'
]
I have written this function however it produces the wrong output. Next to that, I would like to rewrite said function to a macro for Collection
but I cannot wrap my head around it. The problem is also that the current function as is requires a global var to keep track of the result.
public function dotFlattenArray($array, $currentKeyArray = []) {
foreach ($array as $key => $value) {
$explodedKey = preg_split('/[^a-zA-Z]/', $key);
$currentKeyArray[] = end($explodedKey);
if (is_array($value)) {
$this->dotFlattenArray($value, $currentKeyArray);
} else {
$resultArray[implode('.', $currentKeyArray)] = $value;
array_pop($currentKeyArray);
}
}
$this->resultArray += $resultArray;
}
So my problem is twofold: 1. Sometimes the function does not give the right result 2. How can I rewrite this recursive function to a macro
Collection::macro('dotflatten', function () {
return ....
});
The thing you are trying to do is called transform an multidimensional array to array with dot notation.
You don't need to reinvent the wheel, Laravel have already a helper for it, called array_dot().
The array_dot function flattens a multi-dimensional array into a single level array that uses "dot" notation to indicate depth:
$array = ['products' => ['desk' => ['price' => 100]]];
$flattened = array_dot($array);
// ['products.desk.price' => 100]
You only need to transform your json to array with json_decode()
and then flat it with array_dot()
to get an array with dot notation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With