accessing specific elements of arrays in a foreach loop - php

I apologize if this is a very simple question - I've read through tons of posts here, but my question is syntactically very hard to search for, so I haven't found an answer yet.
I have a json array that's output from a company's API:
[Result] => Array
(
[cData] => Array
(
[0] => Array
(
[Reqa] => ABCD
[Reqb] =>
[Reqc] => Plus
[dto] => Array
(
[0] => Array
(
[ComID] => 43292392
[Comment] => Dave
)
[1] => Array
(
[ComID] => 43292392
[Comment] => Bob
)
)
[XREFSearchOperation] => Exact
)
[1] => Array
(
[Reqa] => BCDE
[Reqb] =>
[Reqc] => A
[dto] => Array
(
[0] => Array
(
[ComID] => 19331186
[Comment] => Mike
)
[1] => Array
(
[ComID] => 19331186
[Comment] => Roger
)
)
[XREFSearchOperation] => Starts With
)
[2] => Array
(
[Reqa] => QQDT
[Reqb] =>
)
)
)
)
and I'm trying to access the [ComID] and [Comment] elements, if they exist, inside of a foreach loop and assign it to the variable $y
So far I have:
foreach ($json['Result']['cData']['dto'] as $i) {
$y = "{$i['ComID']}|{$i['Comment']}";
}
but this gives me zero results. I understand WHY, because in between ['cData'] and ['dto'] are [0], [1], [2] etc.. elements, and I don't know how to add a qualifier for those into the loop.
Update
This code works for most of the json response:
foreach ($json['Result']['cData'] as $i) {
if(array_key_exists('dto', $i)) {
foreach ($i['dto'] as $j) {
$y = "{$j['ComID']}|{$j['Comment']}";
} else {
}
}
However - I'm having one more small issue. If there are multiple [dto] responses, you'll have [dto][0][ComID] then [dto][1][ComID] and [dto][2][ComID], (like in the example above,) but if there's only ONE response, you'll have [dto][ComID] as there's no need for that middle array.
I tried writing if(array_key_exists('dto[0]' to execute one, then an else statement in the event dto[0] doesn't exist, but that didn't work. I need a way of NOT executing a foreach loop if there is no array underneath it to "foreachicize". Is there an if/else statement I can write to accommodate this?

Probably need a nested foreach:
foreach ($json['Result']['cData'] as $i) {
foreach($i['dto'] as $j) {
$y[] = "{$j['ComID']}|{$j['Comment']}"; //need an array here
}
}
For the update to the question. Check if $i['dto'][0] exists:
foreach ($json['Result']['cData'] as $i) {
if(isset($i['dto'][0]))) {
foreach($i['dto'] as $j) {
$y[] = "{$j['ComID']}|{$j['Comment']}";
}
} else {
$y[] = "{$j['ComID']}|{$j['Comment']}";
}
}
There might be a better way but I'm headed out.

Another approach:
foreach($json['Result']['cData'] as $cData)
{
foreach($cData['dto'] as $dto)
{
if(array_key_exists('ComID', $dto) && array_key_exists('Comment', $dto))
{
$y = "{$dto['ComID']}|{$dto['Comment']}";
}
}
}

Related

How to update an Associative Array

I do not know what is wrong with my php code. I want to have an Associative Array in the format. When I run my code I get this data. [KY] is an array in the [OH] array.
Array ( [Oh] => Array ( [state] => Oh ) [income] => 100 [count] => 1 [Ky] => Array ( [state] => Ky ) )
Array (
[OH] => Array
( [income] =>
[count] =>
)
[KY] => Array
( [income] =>
[count] =>
)
Here is my code
Example data in $array
Array ( [0] => Array (
[SurveyDate] => 1952-06-21
[Income] => 100
[CountyState] => Hamilton|Oh
[count] => 1 ) )
function update_array_value3( $array )
{
foreach ($array as $row)
{
$arrCountyState = explode( "|", $row['CountyState'] );
$key = $arrCountyState[1]; // OH or KY
if( !isset( $_SESSION['sIncome'][$key] ) )
{
$_SESSION['sIncome'][$key]['state'] = $key;
$_SESSION['sIncome'][$key]['income'] = $row['Income'];
$_SESSION['sIncome'][$key]['count'] = 1;
} else
{
$_SESSION['sIncome'][$key]['state'] = $key;
$_SESSION['sIncome'][$key]['income'] += $row['Income'];
$_SESSION['sIncome'][$key]['count'] += 1;
}
}
I can't tell you the root cause of the problem simply based on this snippet of code, but it seems $row either doesn't contain the data you expect it to, or doesn't contain any data.
In your code you reference $row['CountyState'], yet I don't see any array item called CountyState in $array.
Also, I'm not sure whether or not this is intentional, but in your foreach() loop it looks like $_SESSION['sIncome']['income'] and $_SESSION['sIncome']['count'] are being overwritten. Each time the loop encounters a new $key, it will overwrite those values.

php foreach with one and a lot elements

For example I have code like this, I'm doing foreach loop and it works fine
foreach ( $response['albums']['album'] as $key=>$album ) {
echo($album['artist']['name']);
}
The content of $response is
[albums] => Array
(
[album] => Array
(
[0] => Array
(
[name] => Recovery
[playcount] => 1176206
)
[1] => Array
(
[name] => The Eminem Show
[playcount] => 948632
)
)
)
But, when the source of $response consist only from one element, i have such code, and foreach loop will not work.
[albums] => Array
(
[album] => Array
(
[name] => Doo-Wops & Hooligans
[playcount] => 1106732
)
)
So the question is how to let it work with minimal changes. Please excuse me for my beginner English.
Try like this..
if(array_key_exists(0,$response['albums']['album']))
{
foreach ( $response['albums']['album'] as $key=>$album ) {
echo($album['artist']['name']);
}
}
else
{
foreach ( $response['albums']['album'] as $album ) {
echo $album['name'];
}
}
foreach ( $response['albums'] as $album ) {
if(isset(album['name']))
{
echo $album['artist']['name'];
}
else
{
foreach($album as $val)
{
echo $val['artist']['name'];
{
}
}
That will work, although ideally your array should look like:
[albums] => Array
(
[0] => Array
(
[name] => Recovery
[playcount] => 1176206
)
[1] => Array
(
[name] => The Eminem Show
[playcount] => 948632
)
)
That way even if there is still one you can foreach it.
it will be better to keep consistent structure of input array $response to use single loop otherwise you can try following.
if(count($response['albums']) == 1){
foreach($response['albums'] as $key =>$val) {
echo $val['album']['name'];
}
}
else {
foreach ( $response['albums']['album'] as $key=>$album ) {
echo($album['artist']['name']);
}
}

Iterate though a Object and echo values

I tried a lot of different methods. I managed to get the first part working but the second part to get the fruits name isn't working.
I have an object stored in $food, the print_r() output of this object is shown below:
Food Object
(
[id] => 1
[values] => Array
(
[name] => Myfood
)
[objects] => Array
(
[0] => Fruits Object
(
[id] => 1
[values] => Array
(
[name] => My Fruits
)
[objects] => Array
(
[0] => FruitType Object
(
[id] => 1
[values] => Array
(
[name] => Orange1
)
)
)
)
)
)
This code displays 'Myfood' successfully:
foreach ($food->values as $key => $value) {
echo "$key => $value";
}
This code displays 'My fruits' successfully:
echo '<br/>';
foreach ($food->objects as $id => $owner) {
foreach ($owner->values as $key => $value) {
echo "$key => $value";
}
}
I need a second block of code that displays the FruitType object values Orange1, I tried a few things but didn't work out well.
It looks as if you've run into the greatest stumbling block all developers face... naming things. I've probably not done too much better as I'm not 100% sure what your end goal is but you were on the right track as far as nesting loops is concerned.
foreach ($food->objects as $i => $obj) {
echo "name => {$obj->values['name']}\n";
foreach ($obj->objects as $j => $type) {
foreach($type->values as $key => $val){
echo " $key => $val\n";
}
}
}
Working Example
Looking at the structure of your object though - recursive iteration may be more readable.
Why don't you just use the get_object_vars() function ?
see more here : http://php.net/manual/fr/function.get-object-vars.php

Getting all values from a specific array within a multidimentional array

I've been searching around quite a bit for an answer for this, but I'm afraid that I've been unable to figure out a solution to this problem. I've created a multidimensional array which includes zip code information. However, I've been unable to pull the values out of it in the way that I need to. Here's an example of the print_r():
Array (
[0] => Array (
[0] => 59101
[1] => 0.0 )
[1] => Array (
[0] => 59102
[1] => 5.0 )
[2] => Array (
[0] => 59105
[1] => 6.8 )
[3] => Array (
[0] => 59106
[1] => 9.2 )
[4] => Array (
[0] => 59037
[1] => 12.7 )
[5] => Array (
[0] => 59044
[1] => 13.9 )
[6] => Array (
[0] => 59002
[1] => 16.6 )
[7] => Array (
[0] => 59079
[1] => 19.3 )
)
I need to look through the array for a specific zip code, and then get distance (the second value in each array) associated with that zip code. I'd considered restructuring the array, but I'm unsure of how to accomplish it. Here's my current code:
EDIT## sorry, I may not have been clear. The below code is what I'm using to build the array, not to extract information from the array. I have not idea how to get the information out of the array.
$rArray = array();
foreach ($points as $point){
$zips = $point->Postcode;
$dists = number_format($point->D,1);
array_push($rArray,array($zips,$dists));
}
Any thoughts on the best way to accomplish this? Thanks!
This?
EDIT: After your question update.
function getDistanceByZip($zip) {
$array = //your array here;
foreach($array as $value) {
if($zip == $value[0]) {
return $value[1];
}
}
return false;
}
Maybe this?
foreach ($points as $point){
if ($point->Postcode === $codeIamLookingFor) {
echo "Distance: " . number_format($point->D, 1);
}
}
function arrayseek($array, $zip){
foreach($array as $k => $v){
if($v[0] == $zip){
return $v[1];
}
}
return false;
}

combining arrays in php

Lets say I want to combine 2 arrays and the arrays are names $year_into and $likes_dislikes. They share a key called "name". How can I make it so that this one:
$year_info
Array
(
[0] => Array
(
[name] => JOE MONROE
[year] => 1950
[info] => his ghost still haunts us
)
[1] => Array
(
[name] => FUTUREMAN
[year] => 1930
[info] => RIP
)
)
and this one $likes_dislikes
Array
(
[0] => Array
(
[name] => JOE MONROE
[likes] => cornbread
[dislikes] => pain
)
[1] => Array
(
[name] => E. Case
[likes] => chaos
[dislikes] => order
)
[2] => Array
(
[name] => FUTUREMAN
[likes] => mustard
[dislikes] => mayo
)
)
Can be combined into one array $complete that looks like this, where the information from the 2nd array is added to the 1st if the "name" value matches:
Array
(
[0] => Array
(
[name] => JOE MONROE
[year] => 1950
[info] => his ghost still haunts us
[likes] => cornbread
[dislikes] => pain
)
[1] => Array
(
[name] => FUTUREMAN
[year] => 1930
[info] => RIP
[likes] => mustard
[dislikes] => mayo
)
)
I've looked through the already asked questions but don't see anything, maybe I'm using the wrong terminology to describe the problem. I'm stuck on the foreach loop because if I say like this
foreach ($year_info as $y){
$complete[]=array('name'=>$y['name'], 'year'=>$y['year'], 'info'=>$y['info'], 'likes'=$likes_dislikes[0]['likes'],'dislikes'=>$likes_dislikes[0]['dislikes'] )
}
I'll just get the same values for likes/dislikes for all. What is the simplest way to do this?
Here's a crazy one-liner (I guess it technically counts as one line), that should work.
$complete = array_map(function($a) use($likes_dislikes){
foreach($likes_dislikes as $ld){
if($a['name'] === $ld['name']){
return $a + $ld;
break;
}
}
}, $year_info);
This will only work in PHP 5.3+, otherwise you can do it like this:
$complete = array();
foreach($year_info as $a){
foreach($likes_dislikes as $ld){
if($a['name'] === $ld['name']){
$complete[] = $a + $ld;
break;
}
}
}
What I would try to do is loop through both sets of arrays (a nested foreach loop would be a good choice), checking for instances where The name attribute is the same in both arrays. When they are, you can use array_merge() to merge them into a new array. An example would be:
$newArray = array();
foreach ($arr1 as $first) {
foreach ($arr2 as $second) {
if($first["name"] == $second["name"]){
array_push($newArray, array_merge($first, $second));
}
}
}
Assuming you named your arrays $arr1 and $arr2.
The super-lazy, extra-expository approach:
$complete = array();
foreach($year_info as $yr){
$name = $yr['name'];
foreach($likes_dislikes as $ld){
if($ld['name']!=$name){
continue;
}else{
$new_entity = array();
$new_entity['name'] = $name;
$new_entity['year'] = $yr['year'];
$new_entity['info'] = $yr['info'];
$new_entity['likes'] = $ld['likes'];
$new_entity['dislikes'] = $ld['dislikes'];
$complete[] = $new_entity;
break;
}
}
}
Though this will perform poorly with large arrays, it would make more sense to change the data structure if possible. It would be better to have data structures that were simply keyed by name. Do you have control over your input?
just loop over both arrays to create a third one.
$complete = array();
foreach ($year_info as $year) {
foreach ($like_dislikes as $like {
if ($year['name'] == $like['name']) {
$complete[] = array_merge($year, $like);
}
}
}

Categories