Home > Enterprise >  Use array keys as a prefix to the values for the nested array to generate a string of addresses or p
Use array keys as a prefix to the values for the nested array to generate a string of addresses or p

Time:10-29

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 
)
  • Related