I am struggling to return values from all layers of a multidimensional array, e.g. value then all child elements. I've tried lots of loops but can't quite get it right. Please can someone help - I've been stuck for ages! Thank you.
The array is:
Array
(
[SiteRep] => Array
( [DV] => Array
(
[Location] => Array
(
[Period] => Array
(
[0] => Array
(
[value] => 2016-12-19Z
[Rep] => Array
(
[0] => Array
(
[D] => W
[F] => 1
[G] => 9
)
[1] => Array
(
[D] => W
[F] => 0
[G] => 7
)
)
)
[1] => Array
(
[value] => 2016-12-20Z
[Rep] => Array
(
[0] => Array
(
[D] => ENE
[F] => 4
[G] => 7
)
[1] => Array
(
[D] => E
[F] => 3
[G] => 9
)
so far my code is:
$i=0;
foreach ($json_decoded['SiteRep']['DV']['Location']['Period'][$i] as $key => $value) {
if (is_array($value)){
foreach ($value as $key2 => $value2){
if (is_array($value2)){
foreach ($value2 as $key3 => $value3) {
echo $key3 . " 3: " . $value3 . "<br>";
}
} else {
echo $key2 . " 2: " . $value2 . "<br>";
}
};
} else {
echo $key . " 1: " . $value . "<br>";
}
$i++;
};
I believe you are looking for recursion. A function that calls itself. It can be tricky but it is by far the most efficient way to navigate an array of indeterminate depth.
function printStuff($stuff)
{
echo $stuff['value']
if (isset($stuff['rep']))
{
printStuff($stuff['rep']);
}
}
If you want the values to pass down simply change echo to a return value:
function printStuff($stuff)
{
$temp = $stuff['value']
if (isset($stuff['rep']))
{
$temp .= printStuff($stuff['rep']);
}
return $temp;
}
Note: recursion can cause out of memory if not set up correctly similar to an infinite loop, as the recursive function call pushes the function call onto the call stack every time. Just make sure your function call has a subset of the parameter passed in.
If your array has the constantly number of layers, you may use foreach-function for the each layer. If your array has different number of layers every time - you should use the recursion, because it's the only solution in your situation.
Something like this:
array_walk_recursive($array, function($item, $key){
//your actions
});
I've continued drilling down and managed to get all the data I need by using...
foreach ($json_decoded['SiteRep']['DV']['Location']['Period'] as $key => $value) {
if (is_array($value)){
foreach ($value as $key2 => $value2){
if (is_array($value2)){
foreach ($value2 as $key3 => $value3) {
foreach ($value3 as $key4 => $value4) {
echo $key4 . ": " . $value4 . "<br>";
}
}
} else {
echo $key2 . ": " . $value2 . "<br>";
}
};
} else {
echo $key . ": " . $value . "<br>";
}
$i++;
};
This can map the array recursivly. Preserving they keys and structure.
You can however only return a new value and not change the key. But you will know which key you are looking at and if you just want to echo it you can do that to.
array_map_assoc_recursive('callback', $array)
function callback($key, $value) {
return "new" . $value;
}
function array_map_assoc_recursive($f, array $a) {
return array_column(array_map(function ($key, $value) use ($f) {
if (is_array($value)) {
return [$key, array_map_assoc_recursive($f, $value)];
} else {
return [$key, call_user_func($f, $key, $value)];
}
}, array_keys($a), $a), 1, 0);
}
Related
This question already has answers here:
PHP recursive array searching
(3 answers)
Closed 2 years ago.
That's a short version of the array I'm working with:
Array
(
[orders] => Array
(
[0] => Array
(
[id] => 123
[email] => somemail#mail.com
[line_items] => Array
(
[0] => Array
(
[id] => 456
)
)
)
)
)
I'd like to loop through it and echo out every $key => $value pair but keep track of the "parent" array.
When using this function:
function recursive($array, $level = 0){
foreach($array as $key => $value){
if(is_array($value)){
recursive($value, $level + 1);
} else{
echo $key . ": " . $value, "\n";
}
}
}
i get:
id: 123
email: somemail#mail.com
id: 456
and I would like to keep the parent array in front of the values so that i know which id is echoed out.
orders_0_id: 123
orders_0_email: somemail#mail.com
line_items_0_id: 456
Updated working solution:
function recursive($array, $level = -1,array $parentKey = []){
foreach($array as $key => $value){
$newKey = array_merge($parentKey, [$key]);
if(is_array($value)){
recursive($value, $level + 1, $newKey);
} else{
$parent = implode('_', $newKey);
echo $parent . ": " . $value, "\n";
}
}
}
I think this is what you are looking for, but it might be too much information.
Given this array:
$data = [
'orders' => [
[
'id' => 123,
'email' => 'text#example.com',
'line_items' => [
[
'id' => 356,
],
],
],
],
];
You can keep track of the parent key in an array:
function dumper(array $array, array $parentKey = [])
{
foreach ($array as $key => $value) {
$newKey = array_merge($parentKey, [$key]);
if (is_array($value)) {
dumper($value, $newKey);
} else {
$s = implode('_', $newKey) . ": " . $value . "\n";
echo $s . PHP_EOL;
}
}
}
dumper($data);
This produces:
orders_0_id: 123
orders_0_email: text#example.com
orders_0_line_items_0_id: 356
Hello I am having hard time looping through the PHP multidimensional array, I want to know the best possible way of looping an array. This is the current array that I am trying to loop through.
Array
(
[bathroom] => Array
(
[name] => Bathroom
[things] => Array
(
[0] => Array
(
[name] => Cheval Mirrow
[cubic] => .14
[quantity] => 1
)
[1] => Array
(
[name] => Carton/Wine
[cubic] => .07
[quantity] => 1
)
[2] => Array
(
[name] => Carton/picture
[cubic] => .07
[quantity] => 1
)
)
)
)
I have tried this code
$keys = array_keys($array);
for($i = 0; $i < count($array); $i++) {
echo $keys[$i] . "<br>";
foreach($array[$keys[$i]] as $key => $value) {
echo $key . " : " . $value . "<br>";
foreach($array[$value[$i]] as $key1 => $value1){
echo $key1.":". $value1."<br>";
}
}
echo "<br>";
}
I am able to get the first value now the issues is that I am not able to get the values of things array, I am getting error on this, can someone tell me where I am getting wrong on this.
Here's an example of how you can process your array:
foreach ($array as $key => $value) {
echo "$key:<br>\n";
echo " name: {$value['name']}<br>\n";
foreach ($value['things'] as $t => $thing) {
echo "\tthing $t:<br>\n";
foreach ($thing as $name => $val) {
echo "\t $name: $val<br>\n";
}
}
}
Output:
bathroom:<br>
name: Bathroom<br>
thing 0:<br>
name: ChevalMirrow<br>
cubic: 0.14<br>
quantity: 1<br>
thing 1:<br>
name: Carton/Wine<br>
cubic: 0.07<br>
quantity: 1<br>
thing 2:<br>
name: Carton/picture<br>
cubic: 0.07<br>
quantity: 1<br>
Demo on 3v4l.org
foreach ($orginalarray as $key1 => $value1){
foreach ($value1 as $key2 => $value2) {
foreach ($value2 as $key3 => $value3) {
foreach ($value3 as $key3 => $value3) {
}
}
}
}
Array
(
[edit] => true
[id] => 1
[type] => Array
(
[0] => LC
)
[userid] => 1
[norooms] => 1
[park] => Central
[start] => 09:00
[end] => 11:00
[length] => 2
[student] => 79
[status] => Rejected
)
<?php
$posted_data = array();
if (!empty($_POST['edit'])) {
$posted_data = json_decode($_POST['editVal'], true);
}
print_r ($posted_data);
foreach ($posted_data as $key => $value) {
echo '<p>'.$key.'</p>';
echo '<p>'.$value.'</p>';
}
?>
The array at the top is the jason_decode returned. However with my foreach function it does not display the first index of the array within the array. ie. ( [0] => LC ).
Where am I going wrong?
You need to build a recursive function, something like:
function print_recursively(array $array)
{
foreach ($array as $key => $value)
{
if(is_array($value))
{
print_recursively($value);
}
else
{
echo '<p>'.$key.'</p>';
echo '<p>'.$value.'</p>';
}
}
}
Tune it according to your needs.
If you know there is array hierarchy to one level only
Keep printing the values and if the value is an array using is_array.. Iterate again.
foreach($dataArray as $key =>$value){
if(is_array($value)){
foreach($value as $array2Data){
echo $array2Data; //you can use keys as well
}
}
else
echo $value;
}
I have an array $all_urls. If I do print_r($all_urls);, it will return the following data:
Array (
[0] => http://www.domain.com
[1] => https://www.domain.com
[2] => http://www.domain.com/my-account/
[3] => https://www.facebook.com/
[4] => /test
[5] => http://domain.com/wp-content/uploads/logos-5.jpg
[6] => 'http://domain.com/wp-content/themes/'
[7] => '//mattressandmore.com/wp-content/plugins'
)
I would like to extract and list the items that contain "http://" only.
Use this code to filter only the values that begin with http and return a new array:
array_filter($arr, function ($var) {
return stripos($var, 'http', -strlen($var)) !== FALSE;
});
Try to use array_walk function like this:
array_walk($all_urls, function(function(&$value, $index){
if (preg_match('/^http/', $value)) {
echo $index . " " . $value . "\n";
}
});
Also you can just iterate on array with foreach:
foreach($all_urls as $index => $value) {
if (preg_match('/^http/', $value)) {
echo $index . " " . $value . "\n";
}
}
Below is foreach and the 3 dimension arrays, no problem with the looping but i cannot sepcify which array to echo, they must me the whole arrays like echo $subvalue, any better solutions with looping 3 dimension array? i actually feel weird with this looping. Thanks in adv
foreach ($stories as $key => $story){
//echo "<br />";
foreach($story as $subkey => $subvalue){
echo $subvalue."<br />";
foreach($subvalue as $key => $subsubvalue){
echo $subsubvalue."<br />";
}
}
}
Array
(
[270] => Array
(
[uid] => 36
[user_email] => aaa#hotmail.com
[sid] => 270
[story_name] => Story C
[photo_url] => Array
(
[0] => story_photos/2012/0322/361332381418153311.jpg
[1] => story_photos/2012/0322/361332393792911587.jpg
)
[photo_added_date] => Array
(
[0] => 1332381418
[1] => 1332393792
)
)
[269] => Array
(
[uid] => 36
[user_email] => aaa#hotmail.com
[sid] => 269
[story_name] => Story B
[photo_url] => Array
(
[0] => story_photos/2012/0322/361332381406580761.jpg
)
[photo_added_date] => Array
(
[0] => 1332381406
)
)
[268] => Array
(
[uid] => 36
[user_email] => aaa#hotmail.com
[sid] => 268
[story_name] => Story A
[photo_url] => Array
(
[0] => story_photos/2012/0322/361332381393552719.jpg
)
[photo_added_date] => Array
(
[0] => 1332381393
)
)
)
Why not try this :
foreach ($stories as $key => $story){
if(is_array($story)){
foreach($story as $subkey => $subvalue){
if(is_array($subvalue)){
foreach($subvalue as $key => $subsubvalue){
echo $subsubvalue."<br />";
}
} else {
echo $subvalue."<br />";
}
}
} else {
echo $story."<br />";
}
}
Also, I am not sure because your question isn't really clear or specified.
Or
function echoArray( $array )
{
foreach ($array as $key => $cell)
{
if ( true == is_array($cell) )
{
echoArray($cell);
}
else
{
echo "$cell<br />";
}
}
}
It works for N dimensionnal array
An improved version to know the depth and use different css class for depth and to use set the tag in which the value should be added:
Eg: for depth 0 the class will by arrayclass_0, for depth 1 arrayclass_1, etc...
/**
$array : The array
$depth: The depth ( you should always set it to 0)
$cssclassprefix: The css class prefix you want to set
$tag: the default tag to use to render
$arraytagkey: An optionnal key in your array to extract the tag to use
*/
function echoArray( $array, $depth=0, $cssclassprefix='arrayclass_', $tag='div', $arraytagkey = '' )
{
if ( 0 != strcmp($arraytagkey) && isset($array[$arraytagkey]) )
{
$tag=$array[$arraytagkey];
}
foreach ($array as $key => $cell)
{
if ( true == is_array($cell) )
{
echoArray($cell, $depth+1, $cssclassprefix, $tag, $arraytagkey);
}
else
{
$matches = array();
if ( 0 != preg_match("/^(img|iframe|input)$/i",$tag) )
{
if ( 0 != strcasecmp('input',$tag) )
{
echo "<input class='$cssclassprefix$depth' value='$cell' />";
}
else
{
echo "<$tag class='$cssclassprefix$depth' src='$cell' />";
}
}
else if( 0 != preg_match("/^(br|hr)$/i",$tag) )
{
echo "$cell<$tag />";
}
else
{
echo "<$tag class='$cssclassprefix$depth'>$cell</$tag>";
}
}
}
}
This doesn't really answer your question, but note, your third loop is this:
foreach ($subvalue as $key => $subsubvalue){
But you've already used $key in the first loop:
foreach ($stories as $key => $story){
You should change the third to:
foreach ($subvalue as $subsubkey => $subsubvalue){
Are you just wanting to loop through and get access to the photo_urls and other data? If that's the case then here's a simple example of how you can access the data:
foreach($stories as $key => $story)
{
// here you can echo the $store['user_email'] etc
echo 'Email: ' . $story['user_email'] . '<br />';
// loop over the photo urls
foreach($story['photo_url'] as $photo_url)
{
echo 'Photo URL: ' . $photo_url . '<br />';
}
// loop over the photo added dates
foreach($story['photo_added_date'] as $photo_added_date)
{
echo 'Photo Date: ' . $photo_added_date . '<br />';
}
}
If you're wanting to recursively search the array then the other answers are what you want.