loop through multidimensional array in php - php

some time small things in programming get giants. I am working on 2 dimensional array but I am unable to get what I need.
below is my array structure.
Array
(
[0] => Array
(
[0] => 16
[id] => 16
[1] => 1
[userid] => 1
[2] => abc#gmail.com
[email] => abc#gmail.com
[3] => dffsdf
[message] => dffsdf
[4] => 0
[status] => 0
)
[1] => Array
(
[0] => 17
[id] => 17
[1] => 1
[userid] => 1
[2] => xyz#gmail.comnnn
[email] => xyz#gmail.comnnn
[3] => dffsdfnnnnnnnnnnn
[message] => dffsdfnnnnnnnnnnn
[4] => 0
[status] => 0
)
)
what I am doing here is getting the messages for a user with some id. I am doing it like that
if($get_mails[0]['userid'] == $_GET['userid'])
{
$last_key = end(array_keys($get_mails));
echo '{"Messages":[';
foreach($get_mails as $key => $get_each_mail){
$company_name = $get_each_mail['company_name'];
$email_id = $get_each_mail['id'];
$email_body = $get_each_mail['message'];
}
echo '{"CompanyName":"'.$company_name.'","MessageID":"'.$email_id.'","MessageBody":"'.$email_body.'"';
if ($key == $last_key)
{
echo '}]}';
}else{
echo'},';
}
}
what I am unable to do is so funny that I need a loop for [0] in this line of code
if($get_mails[0]['userid'] == $_GET['userid'])
like
if($get_mails[i]['userid'] == $_GET['userid']) and it give me all the records against specific user.
here is what I want to get for a specific user
{"Messages":[{"CompanyName":"newtech","MessageID":"14","MessageBody":"hi how are you"},{"CompanyName":"newtech","MessageID":"15","MessageBody":"hi how are you"},{"CompanyName":"newtech","MessageID":"24","MessageBody":"asfasdfsdfsdfsdfsdfsdfsdfsd"}]}
respose like that, it will add more and more if more records would available against specific user.

Assuming $get_mails contains the Array you posted above (including company_name), you can write something like this:
$output = Array( "Messages" => Array() );
foreach( $get_mails as $k => $arr ) {
$t = Array();
$t['CompanyName'] = $arr['company_name'];
$t['MessageID'] = $arr['id'];
$t['MessageBody'] = $arr['message'];
$output['Messages'][] = $t;
}
echo json_encode( $output );
First you prepare an Array with the structure of your JSON. The syntax $array[] = a will append a to $array. json_encode( ... ) at the end will take care of turning it into valid JSON, even if one of your keys included a quote or other special character that is invalid in JSON.
I believe you only want to display messages from a certain user, and try to accomplish that with if($get_mails[0]['userid'] == $_GET['userid']). I recommend to change your SQL-query to something that accomplishes that, because the performance of your page will greatly increase if you try to crawl through all messages with the following code:
$output = Array( "Messages" => Array() );
foreach( $get_mails as $k => $arr ) {
if( $arr['user_id'] == $_GET['userid'] ) {
$t = Array();
$t['CompanyName'] = $arr['company_name'];
$t['MessageID'] = $arr['id'];
$t['MessageBody'] = $arr['message'];
$output['Messages'][] = $t;
}
}
echo json_encode( $output );

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 - rearranging an array into groups

I have an array of filenames:
Array
(
[2] => 1_1_page2-img1.jpg
[3] => 1_2_page2-img1-big.jpg
[4] => 2_1_page2-img1.jpg
[5] => 2_2_page2-img1-big.jpg
[6] => 3_1_page2-img1.jpg
[7] => 4_1_page2-img1.jpg
[8] => 4_2_page2-img1.jpg
[9] => 5_2_page2-img1.jpg
)
I'm trying to rearrange them so they're grouped together by their first number. I'm guessing I could maybe separate them with a pipe so I could then distinguish them afterwards. Either that or a multidimensional array.
I know I can perform an explode("_",$filename); to get the first and second digits before the underscores.
The catch is even though the beginning numbers should always increment, there won't necessarily be 2 files per initial number.
So I'm either trying to make it into the following:
Array
(
[0] => 1_1_page2-img1.jpg|1_2_page2-img1-big.jpg
[1] => 2_1_page2-img1.jpg|2_2_page2-img1-big.jpg
[2] => 3_1_page2-img1.jpg|
[3] => 4_1_page2-img1.jpg|4_2_page2-img1.jpg
[4] => |5_2_page2-img1.jpg
)
Or something a bit tidier perhaps? I just can't work out the foreach to put them together.
Or is there an array related command that will put them together easier?
My preference would be to store them in subarrays, as this will be much easier to deal with in the long run; so this would be a possibility, given your array is in $arr:
$newarr = array ();
while (list($key, $val) = each($arr)) {
$subarray_index = substr($val, 0, strpos($val, "_"));
$newarr[$subarray_index][] = $val;
}
Is this what you mean?
$arr = Array(
2 => '1_1_page2-img1.jpg',
3 => '1_2_page2-img1-big.jpg',
4 => '2_1_page2-img1.jpg',
5 => '2_2_page2-img1-big.jpg',
6 => '3_1_page2-img1.jpg',
7 => '4_1_page2-img1.jpg',
8 => '4_2_page2-img1.jpg',
9 => '5_2_page2-img1.jpg'
);
function orderArray($pArr){
$first = '0';
$newArr = array();
foreach($pArr as $val){
if(strpos($val,$first) !== 0){
if(substr($val,2,1)==='1'){
$newArr[]=$val;
}else{
$newArr[]='|'.$val;
}
$first = substr($val,0,1);
}else{
$curIndex = count($newArr) - 1;
$newArr[$curIndex] = $newArr[$curIndex].'|'.$val;
}
return $newArr;
}
$result = orderArray($arr);
print "number of values: ".count($result)."<br>";
foreach($result as $value){
print $value."<br>";
}
Just worked it out now based on another post in stackoverflow:
foreach ($scanned_directory as $filename){
$ids = explode("_",$filename);
$groups[$ids[0]][] = $filename;
}
echo "<pre>";
ksort($groups);
print_r($groups);
echo "</pre>";
Displays:
Array
(
[1] => Array
(
[0] => 1_1_page2-img1.jpg
[1] => 1_2_page2-img1-big.jpg
)
[2] => Array
(
[0] => 2_1_page2-img1.jpg
[1] => 2_2_page2-img1-big.jpg
)
[3] => Array
(
[0] => 3_1_page2-img1.jpg
[1] => 3_2_page2-img1-big.jpg
)
[10] => Array
(
[0] => 10_1_page2-img1.jpg
)
[11] => Array
(
[0] => 11_2_page2-img1-big.jpg
)
)
There isn't a nice automated way of doing this, but you could use a simple loop:
$array = [];
foreach ($filename as $file) {
$fields = explode('_', $file);
$array[$fields[0]][$fields[1]] = $file;
}
An example is located here.

PHP loop to get the data I need

I am using an API and am using a few foreach loops to get to the stage that I am at right now. Please see code below with my comments and also the results that I am getting below that.
// get recent_games api data
$recent_games_data = $player->recent_games();
//start arrays for below
$matches = array();
$gameType = array();
$myData = array();
// using foreach loops to dig in to api data
foreach($recent_games_data['gameStatistics']['array'] as $key_match_data => $value_match_data) {
$matches[] = $value_match_data['statistics'];
}
foreach($matches as $key_match) {
$gameType[] = $key_match['array'];
}
foreach ($gameType as $keyz) {
$myData[] = $keyz;
}
The $mydata array outputs this data below.
Array
(
[0] => Array
(
[0] => Array
(
[statType] => TRUE_DAMAGE_DEALT_TO_CHARACTER
[dataVersion] => 0
[value] => 3351
[futureData] =>
)
[1] => Array
(
[statType] => ASSISTS
[dataVersion] => 0
[value] => 14
[futureData] =>
)
[2] => Array
(
[statType] => NUM_DEATHS
[dataVersion] => 0
[value] => 3
[futureData] =>
)
)
[1] => Array
(
[0] => Array
(
[statType] => TRUE_DAMAGE_DEALT_TO_CHARACTER
[dataVersion] => 0
[value] => 331
[futureData] =>
)
[1] => Array
(
[statType] => ASSISTS
[dataVersion] => 0
[value] => 4
[futureData] =>
)
[2] => Array
(
[statType] => NUM_DEATHS
[dataVersion] => 0
[value] => 7
[futureData] =>
)
)
Of course there is much more data but this is basically what I have now. The first array [0] is each match and the second array are the statistics for that match. What I want is how do I get the statistics of each match without hardcoding the match array number, for example below.
$myData[0][0]['statType']
Let me know if you need more info and thank you.
EDIT: sorry for to mention that as new statistics data gets added to the api, the index number changes. IE TRUE_DAMAGE_DEALT_TO_CHARACTER is [0] to begin with but then may change to [1] or [2] etc.
Consider implementing a class for your stats items after parsing through the data (independent of individual match information keys):
class Stat_Item {
function __construct($id, $info) {
$this->id = $id;
if(!empty($info['damage'])
$this->damage_dealt = $info['damage'];
if(!empty($info['assists']))
$this->assists = $info['assists'];
if(!empty($info['deaths']))
$this->deaths = $info['deaths'];
}
}
$parsed_items = array();
foreach($mydata as $match_id => $match) {
$info = array();
foreach($match as $data_point) {
switch($data_point['statType']) {
case TRUE_DAMAGE_DEALT_TO_CHARACTER:
$info['damage'] = $data_point['value'];
break;
case ASSISTS:
$info['assists'] = $data_point['value'];
break;
case NUM_DEATHS:
$info['deaths'] = $data_point['value'];
break;
}
$parsed_items[] = new Stat_Item($match, $info);
}
}
Other than looping through them all, I don't see any way for you to get a particular match without calling it by its index.
You don't need several foreach loops - you can add to all three arrays in a single one. Also, it looks like $gameType and $myData end up containing the same data.
foreach($recent_games_data['gameStatistics']['array'] as $key_match_data => $value_match_data) {
$matches[] = $value_match_data['statistics'];
$gameType[] = $value_match_data['statistics']['array'];
$myData[] = $value_match_data['statistics']['array'];
}
I don't really understand why you don't just put it into the same array so you can access it easily, though:
foreach($recent_games_data['gameStatistics']['array'] as $key_match_data => $value_match_data) {
$matches[] = array('statistics' => $value_match_data['statistics'], 'data' => $value_match_data['statistics']['array']);
}

Checking if array value exists in a PHP multidimensional array

I have the following multidimensional array:
Array ( [0] => Array
( [id] => 1
[name] => Jonah
[points] => 27 )
[1] => Array
( [id] => 2
[name] => Mark
[points] => 34 )
)
I'm currently using a foreach loop to extract the values from the array:
foreach ($result as $key => $sub)
{
...
}
But I was wondering how do I see whether a value within the array already exists.
So for example if I wanted to add another set to the array, but the id is 1 (so the person is Jonah) and their score is 5, can I add the 5 to the already created array value in id 0 instead of creating a new array value?
So after the loop has finished the array will look like this:
Array ( [0] => Array
( [id] => 1
[name] => Jonah
[points] => 32 )
[1] => Array
( [id] => 2
[name] => Mark
[points] => 34 )
)
What about looping over your array, checking for each item if it's id is the one you're looking for ?
$found = false;
foreach ($your_array as $key => $data) {
if ($data['id'] == $the_id_youre_lloking_for) {
// The item has been found => add the new points to the existing ones
$data['points'] += $the_number_of_points;
$found = true;
break; // no need to loop anymore, as we have found the item => exit the loop
}
}
if ($found === false) {
// The id you were looking for has not been found,
// which means the corresponding item is not already present in your array
// => Add a new item to the array
}
you can first store the array with index equal to the id.
for example :
$arr =Array ( [0] => Array
( [id] => 1
[name] => Jonah
[points] => 27 )
[1] => Array
( [id] => 2
[name] => Mark
[points] => 34 )
);
$new = array();
foreach($arr as $value){
$new[$value['id']] = $value;
}
//So now you can check the array $new for if the key exists already
if(array_key_exists(1, $new)){
$new[1]['points'] = 32;
}
Even though the question is answered, I wanted to post my answer. Might come handy to future viewers. You can create new array from this array with filter then from there you can check if value exist on that array or not. You can follow below code. Sample
$arr = array(
0 =>array(
"id"=> 1,
"name"=> "Bangladesh",
"action"=> "27"
),
1 =>array(
"id"=> 2,
"name"=> "Entertainment",
"action"=> "34"
)
);
$new = array();
foreach($arr as $value){
$new[$value['id']] = $value;
}
if(array_key_exists(1, $new)){
echo $new[1]['id'];
}
else {
echo "aaa";
}
//print_r($new);

How can I create multidimensional arrays from a string in PHP?

So My problem is:
I want to create nested array from string as reference.
My String is "res[0]['links'][0]"
So I want to create array $res['0']['links']['0']
I tried:
$result = "res[0]['links'][0]";
$$result = array("id"=>'1',"class"=>'3');
$result = "res[0]['links'][1]";
$$result = array("id"=>'3',"class"=>'9');
when print_r($res)
I see:
<b>Notice</b>: Undefined variable: res in <b>/home/fanbase/domains/fanbase.sportbase.pl/public_html/index.php</b> on line <b>45</b>
I need to see:
Array
(
[0] => Array
(
[links] => Array
(
[0] => Array
(
[id] => 1
[class] => 3
)
)
)
[1] => Array
(
[links] => Array
(
[0] => Array
(
[id] => 3
[class] => 9
)
)
)
)
Thanks for any help.
So you have a description of an array structure, and something to fill it with. That's doable with something like:
function array_create(&$target, $desc, $fill) {
preg_match_all("/[^\[\]']+/", $desc, $uu);
// unoptimized, always uses strings
foreach ($uu[0] as $sub) {
if (! isset($target[$sub])) {
$target[$sub] = array();
}
$target = & $target[$sub];
}
$target = $fill;
}
array_create( $res, "[0]['links'][0]", array("id"=>'1',"class"=>'3') );
array_create( $res, "[0]['links'][1]", array("id"=>'3',"class"=>'9') );
Note how the array name itself is not part of the structure descriptor. But you could theoretically keep it. Instead call the array_create() function with a $tmp variable, and afterwards extract() it to achieve the desired effect:
array_create($tmp, "res[0][links][0]", array(1,2,3,4,5));
extract($tmp);
Another lazy solution would be to use str_parse after a loop combining the array description with the data array as URL-encoded string.
I have a very stupid way for this, you can try this :-)
Suppose your string is "res[0]['links'][0]" first append $ in this and then put in eval command and it will really rock you. Follow the following example
$tmp = '$'.'res[0]['links'][0]'.'= array()';
eval($tmp);
Now you can use your array $res
100% work around and :-)
`
$res = array();
$res[0]['links'][0] = array("id"=>'1',"class"=>'3');
$res[0]['links'][0] = array("id"=>'3',"class"=>'9');
print_r($res);
but read the comments first and learn about arrays first.
In addition to mario's answer, I used another function from php.net comments, together, to make input array (output from jquery form serializeArray) like this:
[2] => Array
(
[name] => apple[color]
[value] => red
)
[3] => Array
(
[name] => appleSeeds[27][genome]
[value] => 201
)
[4] => Array
(
[name] => appleSeeds[27][age]
[value] => 2 weeks
)
[5] => Array
(
[name] => apple[age]
[value] => 3 weeks
)
[6] => Array
(
[name] => appleSeeds[29][genome]
[value] => 103
)
[7] => Array
(
[name] => appleSeeds[29][age]
[value] => 2.2 weeks
)
into
Array
(
[apple] => Array
(
[color] => red
[age] => 3 weeks
)
[appleSeeds] => Array
(
[27] => Array
(
[genome] => 201
[age] => 2 weeks
)
[29] => Array
(
[genome] => 103
[age] => 2.2 weeks
)
)
)
This allowed to maintain numeric keys, without incremental appending of array_merge. So, I used sequence like this:
function MergeArrays($Arr1, $Arr2) {
foreach($Arr2 as $key => $Value) {
if(array_key_exists($key, $Arr1) && is_array($Value)) {
$Arr1[$key] = MergeArrays($Arr1[$key], $Arr2[$key]);
}
else { $Arr1[$key] = $Value; }
}
return $Arr1;
}
function array_create(&$target, $desc, $fill) {
preg_match_all("/[^\[\]']+/", $desc, $uu);
foreach ($uu[0] as $sub) {
if (! isset($target[$sub])) {
$target[$sub] = array();
}
$target = & $target[$sub];
}
$target = $fill;
}
$input = $_POST['formData'];
$result = array();
foreach ($input as $k => $v) {
$sub = array();
array_create($sub, $v['name'], $v['value']);
$result = MergeArrays($result, $sub);
}

Categories