Use variable with part of array path to output array value - php

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?

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)

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 ()>==<{>============>

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.

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]];

Related

PHP - array key within array value

I have a PHP array like this:
$arr = array(
'id' => 'app.settings.value.id',
'title' => 'app.settings.value.title',
'user' => 'app.settings.value.user'
);
I want to remove '.id', '.title' and '.user' in the array values. I want to insert the key of this array at the end of the value. I know, that I can get an array key by passing an array and a value to 'array_search', but I want the key within this one array definition - at the end of it's value. Is this possible?
I don't like this, but I guess it's simple and works:
$arr = array(
'id' => 'app.settings.value',
'title' => 'app.settings.value',
'user' => 'app.settings.value'
);
$result = array();
foreach ($arr AS $key => $value) {
$result[$key] = $value . '.' . $key;
}
You're storing app.settings.value which is the same for all array items, so personally I'd prefer:
$arr = array(
'id',
'title',
'user'
);
function prepend_key($key)
{
return 'app.settings.value.' . $key;
}
$result = array_map('prepend_key', $arr);
With $result containing:
array(
'app.settings.value.id',
'app.settings.value.title',
'app.settings.value.user'
);
At the end of the day, either works :)

How to extract an array that has a given structure and which's key => value matches a given value of an mutlidimensional array?

I have an array consisting of many other arrays, which might also consist of other arrays. Its basically like a navigation hierarchy, one menu link can be a menu with sub menus and so on.
The structure of $mainarray is like this:
'childarray1' => array(
'link' => array(
..
'mykey' => 'valueofinterest'
),
'below' => array() of childarrays
),
'childarray2' => array(
'link' => array(
..
'mykey' => 'somevalue'
)
),
'childarray3' => array(
'link' => array(
..
'mykey' => 'someothervalue'
),
'below' => array() of childarrays
)
Each childarray can have 2 direct child keys, 'links' and optionally 'below'. Within links there is always a key 'mykey', which is the only key that I need to check. If a child array has ['links']['mykey'] == 'valueofinterest', I'd like to have this element returned, like $sub = $mainarray['child1']['below']['child11']['below']['childofinterest'].
'below' means that the childarray has childs itself which can also have below arrays (sub menu..).
My hude problem is that the childarray I try to find can be in any other childarrays'S 'below' key, I dont know the depth (its not too deep, though it can vary). I've tried to mess with foreach loops and while loops and combining those, I just cant figure it out how to get the child array. I want to do it like this:
$value = 'xxx';
$sub = return_sub_menu($value);
function return_sub_menu($value) {
$array = $mainarray();
$sub = array();
// find the child array which's ['link']['mykey'] == $value;
// $sub is now something like:
// 'childarray321' => array(
// 'link' => array(
// ..
// 'mykey' => 'xxx'
// ),
// 'below' => array() of childarrays which i NEEED :)
//
// )
return $sub;
}
I've tried to walk recursively but cant figure out how to return the element :(
function recursiveSearch($array, $value){
foreach($array as $sub){
if ($sub['link']['mykey'] == $value)
return $sub ;
if (!empty($sub['below'])){
$returned = recursiveSearch($sub['below'], $value);
if ($returned !== null)
return $returned ;
}
}
return null ;
}
$sub = recursiveSearch($array, "valueofinterest");
//Returns array with ['link']['mykey'] == $value ;
var_dump($sub);
UPDATE V2
Fixed the function, so it works now
Try like this,
if (array_key_exists('keyvalue', $array)) {
$subarray = $array['keyvalue'];
return $subarray;
}
It will return sub array
here it is.
$finalarray = array_map(create_function('$yourarray', 'return $yourarray["arrayindex"];'), $actualarray );

Get the sub array in a bidimensional array having a particular key/value pair

I have a large PHP array, similar to:
$list = array(
array(
'id' = '3243'
'link' = 'fruits'
'lev' = '1'
),
array(
'id' = '6546'
'link' = 'apple'
'lev' = '2'
),
array(
'id' = '9348'
'link' = 'orange'
'lev' = '2'
)
)
I want to get the sub-array which contains a particular id.
Currently I use the following code:
$id = '3243'
foreach ($list as $link) {
if (in_array($id, $link)) {
$result = $link;
}
}
It works but I hope there is a better way of doing this.
You can
write $link['id']==$id instead of in_array($id, $link) whitch will be less expensive.
add a break; instruction after $result = $link; to avoid useless loops
While this answer wouldn't have worked when the question was asked, there's quite an easy way to solve this dilemma now.
You can do the following in PHP 5.5:
$newList = array_combine(array_column($list,'id'),$list);
And the following will then be true:
$newList[3243] = array(
'id' = '3243';
'link' = 'fruits'; etc...
The simplest way in PHP 5.4 and above is a combination of array_filter and the use language construct in its callback function:
function subarray_element($arr, $id_key, $id_val = NULL) {
return current(array_filter(
$arr,
function ($subarr) use($id_key, $id_val) {
if(array_key_exists($id_key, $subarr))
return $subarr[$id_key] == $id_val;
}
));
}
var_export(subarray_element($list, 'id', '3243')); // returns:
// array (
// 'id' => '9348',
// 'link' => 'orange',
// 'lev' => '2',
// )
current just returns the first element of the filtered array.
A few more online 3v4l examples of getting different sub-arrays from OP's $list.

Multiple keys with same values in an array

Basically what I'm looking to do is have 2+ different keys pointing to the same value.
Something like:
"AP7898",
"AP7841" => array('loadStatusLoad' => '.1.3.6.1.4.1.318.1.1.12.2.3.1.1.2',
'loadStatusStatus => '.1.3.6.1.4.1.318.1.1.12.2.3.1.1.3',
),
both are ap7898 and ap7841 point to the values.
$val = 'hi';
$arr = array(
'a1' => $val,
'a2' => $val
);
or use references
$val = 'hi';
$arr = array(
'a1' => &$val,
'a2' => &$val
);
$val = 'bye'; // both are updated
Why not setup the parent array, setup the first key/value pair, and copy to the second?
$status = array( 'AP7898', 'AP7841' );
$status['AP7898'] = array('loadStatusLoad' => '.1.3.6.1.4.1.318.1.1.12.2.3.1.1.2',
'loadStatusStatus' => '.1.3.6.1.4.1.318.1.1.12.2.3.1.1.3');
$status['AP7841'] = $status['AP7898'];
If you want to have possibility to modify them using either of keys, you are looking for references.

PHP Api - Results/Array question

I have been looking around for PHP tutorials and I found a very detailed one that have been useful to me.
But now, I have a question. The results showed by the API are stored into a $results array. This is the code (for instance):
$fetch = mysql_fetch_row($go);
$return = Array($fetch[0],$fetch[1]);
$results = Array(
'news' => Array (
'id' => $return[0],
'title' => $return[1]
));
My question is.. I want to display the last 10 news.. how do I do this? On normal PHP / mySQL it can be done as:
while($var = mysql_fetch_array($table)) {
echo "do something"
}
How can I make it so the $results can print multiple results?
I have tried like:
while($var = mysql_fetch_array($table)) {
$results = Array(
'news' => Array (
'id' => $return[0],
'title' => $return[1]
));
}
But this only shows me one result. If I change the $results .= Array(...) it gives error.
What can I do?
Thanks!
Edit
My function to read it doesn't read when I put it the suggested way:
function write(XMLWriter $xml, $data){
foreach($data as $key => $value){
if(is_array($value)){
$xml->startElement($key);
write($xml, $value);
$xml->endElement();
continue;
}
$xml->writeElement($key, $value);
}
}
write($xml, $results);
$results[] = Array(
'news' => Array (
'id' => $return[0],
'title' => $return[1]
));
That should do it.
If you are familiar with arrays, this is the equivalent of an array_push();
array_push() treats array as a stack, and pushes the passed variables onto the end of array. The length of array increases by the number of variables pushed. Has the same effect as:
<?php
$array[] = $var;
?>
Use [] to add elements to an array:
$results = array();
while($var = mysql_fetch_array($table)) {
$results[] = Array(
'news' => Array (
'id' => $var[0],
'title' => $var[1]
));
}
}
You can then loop through the $results array. It's not an optimal structure but you should get the hang of it with this.

Categories