0

I have a array that i want to flatten, but i want to add a backslash and all the parent keys to it. I have a example below, can someone help me out? The array can contain more 5 levels

Cars
    Mercedes
    BMW
    Chevrolet
        Caprice
        Other
Motors
    Yamaha
    Suzuki


Cars
Cars\Mercedes
Cars\BMW
Cars\Chevrolet
Cars\Chevrolet\Caprice
Cars\Chevrolet\Other
Motors
Motors\Yamaha
Motor\Suzuki
1
  • What have you tried? You will need a recursive function that checks if the child is an array, and then do that function for each child, etc. Commented Feb 14, 2016 at 20:48

2 Answers 2

4

I've made a quick demo of what you've asked for, but not sure how similar your array matches up to the test one I have here. Let me know if you need some more help, it's an interesting problem.

<?php
$arr = array(
    'val1' => 1,
    'val2' => 2,
    'val3' => array(
        'val3.1' => 1,
        'val3.2' => array(
            'val3.2.1' => 1
            ),
        'val3.3' => 3
        ),
    'val4' => 4
);

function arrayToPath($array, $path = ''){
    $paths_out = array(); 

    foreach($array as $key => $value){
        $path .= '\\' . $key;
        $paths_out[] = $path;
        if(true === is_array($value)){
            $paths_out = array_merge($paths_out, arrayToPath($value, $path));
        }
    }

    return $paths_out;
}

$path_outputs = arrayToPath($arr);
var_dump($path_outputs);
?>

Will output:

array(8) { 
    [0]=> string(5) "\val1" 
    [1]=> string(10) "\val1\val2" 
    [2]=> string(15) "\val1\val2\val3" 
    [3]=> string(22) "\val1\val2\val3\val3.1" 
    [4]=> string(29) "\val1\val2\val3\val3.1\val3.2" 
    [5]=> string(38) "\val1\val2\val3\val3.1\val3.2\val3.2.1" 
    [6]=> string(36) "\val1\val2\val3\val3.1\val3.2\val3.3" 
    [7]=> string(20) "\val1\val2\val3\val4" 
} 
Sign up to request clarification or add additional context in comments.

4 Comments

Impressive, we both posted a very similar answer in practically the same second :-)
I was just thinking the same thing :) Great minds or something, eh?
OK, great minds deserve a reward, just upvoted your answer :-)
I notice your nice condition statement: constant strict-operator function
3

Have a try with this simple recursive approach:

<?php

$catalog = [
    'Cars' => [
        'Mercedes' => [],
        'BMW' => [],
        'Chevrolet' => [
            'Caprice',
            'Other'
        ],
    ],
    'Motors' => [
        'Yamaha',
        'Suzuki'
    ]
];

function flattenCatalog($input, $location='') {
    $output = [];
    foreach ($input as $key=>$val) {
        if (is_array($val)) {
            $output[] = $location.'\\'.$key;
            foreach (flattenCatalog($val, $location.'\\'.$key) as $subval) {
                $output[] = $subval;
            }
        }
        else {
            $output[] = $location.'\\'.$val;
        }
    }
    return $output;
}

print_r(flattenCatalog($catalog));

The output obviously is:

Array
(
    [0] => \Cars
    [1] => \Cars\Mercedes
    [2] => \Cars\BMW
    [3] => \Cars\Chevrolet
    [4] => \Cars\Chevrolet\Caprice
    [5] => \Cars\Chevrolet\Other
    [6] => \Motors
    [7] => \Motors\Yamaha
    [8] => \Motors\Suzuki
)

5 Comments

At a glance, your solution looks slightly more flexible than mine in accepting array entries which are value-only. My sample needs a small tweak to accommodate anything that isn't an associative pair.
@Hiphop03199 That is indeed what I understood to be the challenge in this question. Your answer is slightly more compact, though.
Thats a sweet function :) only 1 issue: take a look at this paste: laravel.io/bin/d9Drn that is my array. Using your function gets me: laravel.io/bin/KknYV so it also gives the created_at (Laravel fields) back to me :P
Sorry, I fail to see an issue here. Your question asks to flatten all entries in the given array. That is what the function does. It cannot somehow magically guess what entries you might want to skip. If you have clear rules about those exception, then you can either extend the routine by implementing exceptions, or, more effective, you clean the input array before flattening it.
Yeah i don't blame you Arka, you gave me a direction and thats something i really appreciate :) You couldn't know that it has integer keys instead of text only. Sorry i forgot to mention.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.