For four days I am trying to figure out how to solve this, as well as googling it, and was no luck
The problem is that I needed to loop through a nested array (for unknown deep) and keep the top-level keys (as a prefix to the last value) as long as I am still going deep, and then start over (the prefix need to reset) once it started a new path.
I want to generate complete addresses from this array.
$arr = [
"buildings" => [
"group1" => [
"b1" => [1,2,3,4],
"b2" => [1,2,3]
],
"group2" => [
"b1" => [1,2]
]
],
"villas" =>[
"group1" => [
"v1" => [1,2],
"v2" => [1]
],
"group2" => [
"v1" => [1],
"v2" => [1]
],
"group3" => [
"v1" => [1]
],
]
];
This is the needed output
buildings/group1/b1/1
buildings/group1/b1/2
buildings/group1/b1/3
buildings/group1/b1/4
buildings/group1/b2/1
buildings/group1/b2/2
buildings/group1/b2/3
buildings/group2/b1/1
buildings/group2/b1/2
villas/group1/v1/1
villas/group1/v1/2
villas/group1/v2/1
villas/group2/v1/1
villas/group2/v2/1
villas/group3/v1/1
I tried this function but also it didn't bring the wanted results
function test($array, $path = ""){
foreach ($array as $key => $value) {
if (is_array($value)){
$path .= $key."/";
test($value, $path);
} else {
echo $path.$value."<br>";
}
}
}
test($arr);
UPDATE
I understood where was my mistake and I wanted to share with you my modification to my method after I fixed it.
function test($array, $path = ""){
foreach ($array as $key => $value) {
if (is_array($value)){
test($value, $path . $key . '/');
} else {
echo $path.$value."<br>";
}
}
}
And thanks to @Kai Steinke he's method is way better than mine, and here is some improvements just to make it look better.
function flatten(array $array, array $flattened = [], string $prefix = ''): array
{
foreach ($array as $key => $value) {
if (is_array($value)) {
$flattened = array_merge( flatten($value, $flattened, $prefix . $key . '/'));
continue;
}
$flattened[] = $prefix . $value;
}
return $flattened;
}
CodePudding user response:
Here you go:
function flatten($arr, $prefix = '') {
$result = [];
foreach ($arr as $key => $value) {
if (is_array($value)) {
$result = array_merge($result, flatten($value, $prefix . $key . '/'));
} else {
$result[] = $prefix . $value;
}
}
return $result;
}
// Usage
print_r(flatten($arr))
Returns an Array:
Array (
[0] => buildings/group1/b1/1
[1] => buildings/group1/b1/2
[2] => buildings/group1/b1/3
[3] => buildings/group1/b1/4
[4] => buildings/group1/b2/1
[5] => buildings/group1/b2/2
[6] => buildings/group1/b2/3
[7] => buildings/group2/b1/1
[8] => buildings/group2/b1/2
[9] => villas/group1/v1/1
[10] => villas/group1/v1/2
[11] => villas/group1/v2/1
[12] => villas/group2/v1/1
[13] => villas/group2/v2/1
[14] => villas/group3/v1/1
)