Count entries in a JSON Array? - php

How do I count the entries I am scraping from JSON?
The below example has 6 entries, but as you can see.. if an entry is added, my code will ignore it. I could loop it 10 times and if it picks up nothing, then stop, but I think that's a bad way of doing it.
Is there any simple code that picks up 6 'seasons' in the following JSON?
MYPAGE.PHP
//Get the page
$str = file_get_contents('http://myjsonurl.here/');
$jsonarray = json_decode($str, true);
$season1 = $jsonarray['season_history'][0][0];
$season2 = $jsonarray['season_history'][1][0];
$season3 = $jsonarray['season_history'][2][0];
$season4 = $jsonarray['season_history'][3][0];
$season5 = $jsonarray['season_history'][4][0];
$season6 = $jsonarray['season_history'][5][0];
//the rest of the info here..
JSON
{
"season_history": [
["2006/07", 2715, 12, 11, 0, 45, 0, 0, 0, 1, 0, 0, 26, 0, 91, 169],
["2007/08", 2989, 15, 11, 0, 56, 0, 0, 0, 3, 0, 0, 18, 0, 95, 177],
["2008/09", 2564, 9, 10, 0, 20, 0, 0, 0, 2, 0, 0, 14, 0, 95, 138],
["2009/10", 2094, 12, 6, 0, 13, 0, 0, 0, 1, 0, 0, 8, 0, 92, 130],
["2010/11", 2208, 21, 4, 8, 28, 0, 0, 0, 1, 0, 0, 26, 0, 92, 176],
["2011/12", 521, 7, 0, 2, 6, 0, 0, 0, 0, 0, 0, 5, 146, 89, 49]
]
}

A foreach loop may be the approach you're looking for.
For example, this code would output the years for each season in your JSON data, regardless of how many seasons there were:
//Get the page
$str = file_get_contents('http://myjsonurl.here/');
$jsonarray = json_decode($str, true);
foreach($jsonarray['season_history'] as $season) {
echo $season[0] . PHP_EOL;
}
Alternatively, if you just need to know the number of seasons, this would be a solution:
//Get the page
$str = file_get_contents('http://myjsonurl.here/');
$jsonarray = json_decode($str, true);
$numberOfSeasons = count($jsonarray['season_history']);
You could combine that with a for loop as well, if you wanted:
for($i = 0; $i < $numberOfSeasons; $i++) {
echo $jsonarray['season_history'][$i][0];
}

Nevermind.. I figured it out... Here is the code I used.
//Get the page
$str = file_get_contents('http://myjsonurl.here/');
$jsonarray = json_decode($str, true);
//FOR EACH SEASON
foreach ($jsonarray['season_history'] as $var)
{
for ($i = 0; $i <= 15; $i++)
{
echo $var[$i];
//do more stuff here
}
}

Related

How to create an array assigning new key in php

I want to create a new array of size 12 from the following array:
$array = [2=>9, 3=>10, 6=>7, 10=>7];
I want the following output:
$array = [1=>0, 2=>9, 3=>10, 4=>0, 5=>0, 6=>7, 7=>0, 8=>0, 9=>0, 10=>7, 11=>0, 12=>0];
Or simply,
$array = [0, 9, 10, 0, 0, 7, 0, 0, 0, 7, 0, 0];
From 1 to 12, if key does not exists, then set value to 0.
Oneliner:
$array = [2=>9, 3=>10, 6=>7, 10=>7];
print_r(array_replace(array_fill(1, 12, 0), $array));

Page Break issues in fpdf and php

I have to generate multiple pages in fpdf by php.on first section i am using multicell.that works fine.after that i am using cell in a loop.
$GetMultiCellHeight = $pdf->y - $y;
$y = $y + $GetMultiCellHeight;
$pdf->SetXY($x, $y);
$pdf->Cell(30, 10, 'FILE NO', 1, 0, 'C');
$pdf->Cell(80, 10, 'FILE NAME', 1, 0, 'C');
$pdf->Cell(30, 10, 'DATE', 1, 0, 'C');
$pdf->Cell(50, 10, 'TYPE', 1, 0, 'C');
$y = $y + 10;
$pdf->SetXY($x, $y);
while ($rowSubmission_files = oci_fetch_row($parse_Submission_files)) {
$pdf->Cell(30, 10, $rowSubmission_files [1], 1, 0, 'C');
$pdf->Cell(80, 10, $rowSubmission_files [2], 1, 0, 'L');
$pdf->Cell(30, 10, $rowSubmission_files [5], 1, 0, 'C');
$pdf->Cell(50, 10, $rowSubmission_files [6], 1, 0, 'L');
$y = $y + 10;
$pdf->SetXY($x, $y);
}
I have two rows in my database to print file details.
after generation of pdf i am getting each rows in a new page. how to solve this?thanks in advance.

How can I choose "at least n" of each type of item in an ordered list

I have a list of results (see JSON below), and I need to choose the top 10. Here they're in json but I'm json_decoding them into an array like $coureValues["BUS1067"] == 117.1
I use arsort($courseValues) to get them in order like JSON below.
I need to choose the top 10, but I need to enforce a constraint of at least 4 "BUS", at least 2 "CMP", and at least 1 SAF. So for example, if there is no SAFxxxx in the top 10, but there are 6 BUS and 2 CMP, I want to remove the lowest scoring BUS and add the highest scoring SAF. In the end, all I want is a php array with the top 10, taking into consideration the constraints.
JSON
{
"BUS1067": 117.1,
"BUS1057": 86.06,
"BUS1073": 79,
"BUS1068": 74.08,
"BUS1077": 74,
"BUS1001": 71,
"BUS1066": 68,
"BUS1076": 67.05,
"BUS1011": 64,
"BUS1054": 64,
"BUS1006": 63,
"CMP1091": 62,
"BUS1000": 60,
"CMP1083": 59,
"SAF1007": 58,
"CMP1073": 56,
"CMP1044": 55,
"CMP1029": 55,
"CMP1082": 53,
"CMP1089": 50,
"CMP1042": 48,
"CMP1070": 46,
"CMP1074": 45,
"BUS1074": 31,
"BUS1009": 20,
"BUS1003": 10,
"BUS1058": 1.09,
"BUS1061": 1.07,
"BUS1056": 1.04,
"CMP1081": 1.03,
"SAF1021": 1.01,
"CMP1064": 0,
"CMP1039": 0,
"CMP1047": 0,
"SAF1045": 0,
"SAF1047": 0,
"CMP1063": 0,
"SAF1020": 0,
"SAF1043": 0,
"SAF1032": 0,
"SAF1038": 0,
"BUS1075": 0,
"SAF1002": 0,
"CMP1037": 0,
"BUS1040": 0,
"CMP1078": 0,
"BUS1013": 0,
"CMP1080": 0,
"BUS1002": 0,
"BUS1048": 0,
"BUS1071": 0,
"CMP1072": 0,
"CMP1088": 0,
"CMP1084": 0,
"BUS1031": 0,
"BUS1055": 0,
"BUS1063": 0,
"BUS1072": 0,
"SAF1013": 0,
"BUS1012": 0,
"SAF1006": 0,
"CMP1049": -20,
"CMP1048": -20,
"CMP1050": -20,
"CMP1075": -20,
"CMP1038": -925,
"CMP1041": -929,
"CMP1079": -933.98
}
what I'm looking for is a simple, elegant way to do that. I could "get it done", but the code that comes to mind is messy and unclear, and it seems that there's some general "algorithm" or sorting function that I should be using.
UPDATE: CODE:
as requested, here is my awful code to do a simple thing
<?php
$jsonWeights='{ "BUS1067": 117.1, "BUS1057": 86.06, "BUS1073": 79, "BUS1068": 74.08, "BUS1077": 74, "BUS1001": 71, "BUS1066": 68, "BUS1076": 67.05, "BUS1011": 64, "BUS1054": 64, "BUS1006": 63, "CMP1091": 62, "BUS1000": 60, "CMP1083": 59, "SAF1007": 58, "CMP1073": 56, "CMP1044": 55, "CMP1029": 55, "CMP1082": 53, "CMP1089": 50, "CMP1042": 48, "CMP1070": 46, "CMP1074": 45, "BUS1074": 31, "BUS1009": 20, "BUS1003": 10, "BUS1058": 1.09, "BUS1061": 1.07, "BUS1056": 1.04, "CMP1081": 1.03, "SAF1021": 1.01, "CMP1064": 0, "CMP1039": 0, "CMP1047": 0, "SAF1045": 0, "SAF1047": 0, "CMP1063": 0, "SAF1020": 0, "SAF1043": 0, "SAF1032": 0, "SAF1038": 0, "BUS1075": 0, "SAF1002": 0, "CMP1037": 0, "BUS1040": 0, "CMP1078": 0, "BUS1013": 0, "CMP1080": 0, "BUS1002": 0, "BUS1048": 0, "BUS1071": 0, "CMP1072": 0, "CMP1088": 0, "CMP1084": 0, "BUS1031": 0, "BUS1055": 0, "BUS1063": 0, "BUS1072": 0, "SAF1013": 0, "BUS1012": 0, "SAF1006": 0, "CMP1049": -20, "CMP1048": -20, "CMP1050": -20, "CMP1075": -20, "CMP1038": -925, "CMP1041": -929, "CMP1079": -933.98 }';
$courseValues=json_decode($jsonWeights,true);
arsort($courseValues);
$minRequired=array("BUS"=>4, "CMP"=>2, "SAF"=>1);
$pathLength=10;
$selected=array();
//get top results to satisfy minimum required
foreach ($minRequired as $courseType => $min) {
foreach($courseValues as $key => $val){
if(substr($key, 0, 3) == $courseType && $min)
{
$selected[$key]=$val;
$min--;
if($min==0)
break;
}
}
}
//fill in the remaining with the top results
foreach($courseValues as $k=>$v){
if(count($selected)<$pathLength)
{
if(!array_key_exists($k, $selected))
$selected[$k]=$v;
}
else
break;
}
arsort($selected);
foreach($selected as $k=>$v)
echo "$k: $v<br>";
?>
$topten = array_keys( array_slice( arsort( $courseValues ), 0, 10) ); ?
okay, sorry for not reading the question thoroughly :)
I would start with creating a php array that has the prefixes as keys and the number needed as values like so:
$prefixes = array("BUS" => 4, "CMP" => 2, "SAF" => 1);
Then, since you need 10 elements and the sum of the values is 7, you pick 3 elements from any category. The loop then should be something like this:
Basic idea:
While you don't have 10 elements from the sorted list:
Get element.
Extract prefix.
If (the prefix exists in the prefix array, and the corresponding value is greater than 0),
or (the sum of the remaining prefix values is less than the number of elements needed), then add it to your result.
In code:
$results = array();
foreach ($courseValues as $course => $courseValue) {
$prefix = substr($course, 0, 3);
if (isset($prefixes[$prefix]) && $prefixes[$prefix--] >= 0) {
$results[$course] = $courseValue;
}
else if (array_sum($prefixes) < 10 - count($results)) {
$results[$course] = $courseValue;
}
if (count($results) == 10) {
break;
}
}
Note: this is assuming $courseValues is sorted by $courseValue
MY SOLUTION:
Ok, I've got it down to one foreach loop. here's the full solution:
$jsonWeights='{ "BUS1067": 117.1, "BUS1057": 86.06, "BUS1073": 79, "BUS1068": 74.08, "BUS1077": 74, "BUS1001": 71, "BUS1066": 68, "BUS1076": 67.05, "BUS1011": 64, "BUS1054": 64, "BUS1006": 63, "CMP1091": 62, "BUS1000": 60, "CMP1083": 59, "SAF1007": 58, "CMP1073": 56, "CMP1044": 55, "CMP1029": 55, "CMP1082": 53, "CMP1089": 50, "CMP1042": 48, "CMP1070": 46, "CMP1074": 45, "BUS1074": 31, "BUS1009": 20, "BUS1003": 10, "BUS1058": 1.09, "BUS1061": 1.07, "BUS1056": 1.04, "CMP1081": 1.03, "SAF1021": 1.01, "CMP1064": 0, "CMP1039": 0, "CMP1047": 0, "SAF1045": 0, "SAF1047": 0, "CMP1063": 0, "SAF1020": 0, "SAF1043": 0, "SAF1032": 0, "SAF1038": 0, "BUS1075": 0, "SAF1002": 0, "CMP1037": 0, "BUS1040": 0, "CMP1078": 0, "BUS1013": 0, "CMP1080": 0, "BUS1002": 0, "BUS1048": 0, "BUS1071": 0, "CMP1072": 0, "CMP1088": 0, "CMP1084": 0, "BUS1031": 0, "BUS1055": 0, "BUS1063": 0, "BUS1072": 0, "SAF1013": 0, "BUS1012": 0, "SAF1006": 0, "CMP1049": -20, "CMP1048": -20, "CMP1050": -20, "CMP1075": -20, "CMP1038": -925, "CMP1041": -929, "CMP1079": -933.98 }';
$courseValues=json_decode($jsonWeights,true);
arsort($courseValues);
$required=array("BUS"=>4, "CMP"=>2, "SAF"=>1,"Total" => 10);
$selected=array();
foreach($required as $type => $min)
foreach($courseValues as $key => $val)
if(count($selected)<$required['Total']
&&($type=='Total'||(substr($key,0,3)==$type && $min-->0)))
$selected[$key]=$val;
I'll leave it open in case anyone has a better idea

How to add queried rows with same values?

I am new to PHP. I have a table that stores the transactions bought. I am to summarize the transactions that happens in between two dates. For example: 2014-03-21 to 2014-03-23
I'm placing this in a fpdf :)
Here's my query:
<?php
$query = "SELECT * FROM tbl_items INNER JOIN tbl_receipts ON tbl_items.item_id=tbl_receipts.item_id WHERE receiptdate >= '$sdate' && receiptdate <='$ldate' ORDER BY tbl_items.item_id";
$result = mysql_query($query);
$row = mysql_fetch_assoc($result);
$addtotal = 0;
$counter = 1;
if (mysql_num_rows($result) != 0) {
while ($row = mysql_fetch_assoc($result)) {
$totaladd = $row['quantity_bought'] * $row['itemquantity_price'];
$item = $row['item_description'];
$num = $row['quantity_bought'];
$pdf->Cell(15, 13, '', 0, 0, 'C');
$pdf->Cell(15, 6, $counter, 1, 0, 'R');
$pdf->Cell(60, 6, $row['item_description'], 1, 0, 'L');
$pdf->Cell(20, 6, $row['quantity_bought'], 1, 0, 'R');
$pdf->Cell(30, 6, $row['itemquantity_price'], 1, 0, 'R');
$pdf->Cell(30, 6, "$totaladd.00", 1, 0, 'R');
$pdf->Ln(6);
$addtotal = $addtotal + $totaladd;
$counter++;
}
}
$pdf->Cell(15, 15, '', 0, 0, 'C');
$pdf->Cell(15, 6, '', 1, 0, 'R');
$pdf->Cell(60, 6, 'SUB-TOTAL', 1, 0, 'L');
$pdf->Cell(20, 6, '', 1, 0, 'R');
$pdf->Cell(30, 6, '', 1, 0, 'R');
$pdf->Cell(30, 6, "$addtotal.00", 1, 0, 'R');
$pdf->Ln(4);
?>
However, after summarizing, I have multiple rows for items with same item_description. I want to add those item quantities to avoid repetition. How can I do it?
Personally, I pass by the array, or I accumulate on the key and then I browse the array.
for example:
$array = array();
while($row = mysql_fetch_assoc($result)){
$array[$row['item_description']]['quantity_bought'] = $row['quantity_bought'];
$array[$row['item_description']]['itemquantity_price'] = $row['itemquantity_price'];
...
}
foreach($array as $item_description => $array_detail){
$item = $item_description;
foreach($array_detail as $key => $value){
if ($key == 'quantity_bought') $num = $value;
...
}
}

How to Sum Columns of a Multi-Dimensional Array?

I have array data like :
[
'A1' => [1, 0, 0, 0, 0, 0, 0, 0, 0, 0],
'A2' => [1, 1, 0, 0, 0, 0, 0, 0, 0, 0],
'A3' => [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
];
I want to add the column values and produce a flat array of sums.
I want answer like this:
[2, 1, 0, 0, 0, 0, 0, 0, 0, 0]
Are there any array functions in php to do this? Otherwise how can I do this?
There's always custom code:
function array_sum_rows($arr) {
$out = array();
foreach ($arr as $row) {
foreach ($row as $i => $val) {
$out[$i] = isset($out[$i]) ? $out[$i] + $val : $val;
}
}
return $out;
}
$multiArray = ... //your array
$sumArray = array();
$i = 1;
foreach ($multiArray as $key => $array) {
$sumArray[$i] = array_sum($array);
$i++;
}
This would work with your array. You will get an array
http://php.net/manual/en/function.array-sum.php
Unfortunately loses the actual index in the transpose:
function array_transpose($arr) {
return call_user_func_array(
'array_map',
array_merge(
array(NULL),
$arr
)
);
}
$transposedArray = array_transpose($myData);
$result = array_map('array_sum', $transposedArray);
var_dump($result);
But the indexes can be restored by
$result = array_combine(array_keys(end($myData)), $result);
"Transpose" the input array (rotate the data 90 degrees so that columns become rows), then feed the new "rows" to array_map() so that each has array_sum() called upon it.
Code: (Demo)
$array = [
'A1' => [1, 0, 0, 0, 0, 0, 0, 0, 0, 0],
'A2' => [1, 1, 0, 0, 0, 0, 0, 0, 0, 0],
'A3' => [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
];
var_export(array_map('array_sum', array_map(null, ...array_values($array))));
*Calling array_values() is necessary before the spread operator (...) until using a php version that doesn't choke on string keys.
Produces flat output array: [2, 1, 0, 0, 0, 0, 0, 0, 0, 0]

Categories