0

I have an array like so:

$cars = array(
  'type' => array(
    'brand' => array(
      'car' => 'Honda',
    ),
  ),
);

And I also have a string like so:

$path = "type][brand][car";

I'd like to return a value of car from $cars array using $path string, but of course this won't work:

echo $cars[$path];

The output I'd like to have is: "Honda". How this should be done?

8
  • Where does the string come from? Commented Mar 22, 2019 at 22:58
  • doesn't matter TBH, I have an array of parents and I generate the string Commented Mar 22, 2019 at 22:59
  • 1
    It does matter, because storing the path in a different way would make your live easier... It's a candidate for an XY Problem Commented Mar 22, 2019 at 23:15
  • Ok, so in this case I have an array of parents for car key, which looks like this: $parents = array('type', 'brand', 'car'); Commented Mar 22, 2019 at 23:18
  • So there's the path already! Next question is what the output of echo $cars[$path]; should be. "Honda"? Commented Mar 22, 2019 at 23:20

4 Answers 4

2

Here is basicly what I understood you want to achieve in a simple function, that uses the parents array to get a nested value:

<?php
$cars = array(
  'type' => array(
    'brand' => array(
      'car' => 'Honda',
    ),
  ),
);

$parents = array('type', 'brand', 'car');

// you could also do:
// $path = "type][brand][car";
// $parents = explode("][", $path);

function GetCar($cars, $parents) {
    foreach($parents as $key) {
        $cars = $cars[$key]; 
        // echo $key."<br>";
    }
    return $cars;
}

var_dump(GetCar($cars, $parents)); // OUTPUT: string(5) "Honda"
echo GetCar($cars, $parents); // OUTPUT: Honda

A snippet: https://3v4l.org/OKrQN

I still think, that there is a better solution for what you need in a bigger picture (that I don't know)

Sign up to request clarification or add additional context in comments.

4 Comments

$cars is passed as value, not by reference, so you wouldn't override it. Again: without the bigger picture it's hard to answer appropriate for you specific needs.
I just removed my last comment. Yep, that makes sense. The thing is you've added a function that doesn't really change $cars array, it just operates on it and it's not passed by referece &. By putting loop directly into code it would override the array, in this case it works as expected. Thanks mate for clarification and sorry for confusion. :)
You're welcome! please consider my last sentence in my answer. This doesn't seem right after all. I think there's something in the logic before that should be done in an other way.
Not sure. That's the data I'm getting ($parents) and I need to operate on it. I fixed myself and never thought of putting just one loop into separate function.
1

Here is the correct answer, I am not just saying that as I've done this many times before. And I have really analyzed the problem etc...

$array = array(
  'type' => array(
    'brand' => array(
      'car' => 'Honda',
    ),
  ),
);

$path = "type][brand][car";


function transverseGet($path, array $array, $default=null){
    $path = preg_split('/\]\[/', $path, -1, PREG_SPLIT_NO_EMPTY);

    foreach($path as $key){
        if(isset($array[$key])){
            $array = $array[$key];
        }else{
            return $default;
        }
    }

    return $array;
}

print_r(transverseGet($path, $array));

Output

Honda

Sandbox

The trick is, every time you find a key from the path in the array you reduce the array to that element.

if(isset($array[$key])){
   $array = $array[$key];

At the end you just return whatever is left, because your out of path parts to run so you can assume its the one you want.

If it doesn't find that key then it returns $default, you can throw an error there if you want.

It's actually pretty simple to do, I have this same setup for set,get,isset - key transversal

Like a Ninja ()>==<{>============>

Comments

0

If you require to use that specific structure you could do something like this:

$path = "type][brand][car";
$path_elements = explode("][", $path);

This way you get an array with each of the components required, and you'll have to do something like:

echo $cars[$path_elements[0]][$path_elements[1]][$path_elements[2]];

Of course that is a little bit too static and needs the same 3 level element structure.

2 Comments

that doesn't resolve my issue as the array is generated somewhere before and I don't know how many nested arrays are there
Is there a particular reason that the structure of the array is like that? And also what originates the path variable?
0

May be this can resolve the problem :

strong text$cars = array(   'type' => array(
    'brand' => array(
      'car' => 'Honda',
    ),   ), );

$path = "type][brand][car";

preg_match_all('/[a-z]+/', $path,$res);
$re = $res[0];

echo $cars[$res[0][$res[1]][$res[2]];

1 Comment

that doesn't resolve my issue as the array is generated somewhere before and I don't know how many nested arrays are there

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.