Combining two seperate arrays each with a different number of elements - php

I'm becoming a little frustrated with my array results. Ideally, I am creating a form maker module within my application and I am working with two different arrays to establish my database columns and excel columns. Essentially, I am using the results provided by the arrays to write directly to a php file (Excel reader file). In order to establish a difference in Excel Workbooks, I am putting forth an identifier "page2","page3" and so on within the "excel_rows" array.
//my arrays
$table_columns = array('field1','field2','field3','field4','field5'); //fields
$excel_rows = array('c1','c2','page2','c3','c4','page3','c5'); //excel columns
From here.. I go on to try to filter the array keys..
foreach(array_keys($excel_rows) as $key){
$page = array_search(strpos(trim($excel_rows[$key]),'page'),$excel_rows);
if(strpos(trim($excel_rows[$key]),'page') !== false){
$excel_row .= '$objTpl->setActiveSheetIndex('.(str_replace('page','',trim($excel_rows[$key])) -1).');<br/>'.PHP_EOL;
$table_columns[$key] = 0;
}
else {
$excel_row .= '$objTpl->getActiveSheet()->setCellValue(\''.trim($excel_rows[$key]).'\',$row[\''.trim($table_columns[$key]).'\']);<br/>'.PHP_EOL;
}
}
print $excel_row;
The result should echo out the following:
$objTpl->getActiveSheet()->setCellValue('c1', $row['field1']);
$objTpl->getActiveSheet()->setCellValue('c2', $row['field2']);
$objTpl->setActiveSheetIndex(1);<br/>
$objTpl->getActiveSheet()->setCellValue('c3', $row['field4']);
$objTpl->getActiveSheet()->setCellValue('c4', $row['field5']);
$objTpl->setActiveSheetIndex(2);
$objTpl->getActiveSheet()->setCellValue('c5', $row['']);
As one can see, I am missing 'field3' from my result and 'cs' produces and empty row rather than "field5".
I'm assuming something like array_compare or array_combine is the solution - I'm just not able to put it together.
Everything works lovely with module pardoning the array code above. Any help with this would be sincerely appreciated!
-Regards.

How it currently is I'd say you need to set an integer +1 whenever you create a new page and then subtract that integer from the key so you can get the right field.
$subkey = 0;
foreach(array_keys($excel_rows) as $key){
$fieldkey = $key - $subkey;
$page = array_search(strpos(trim($excel_rows[$key]),'page'),$excel_rows);
if(strpos(trim($excel_rows[$key]),'page') !== false){
$excel_row .= '$objTpl->setActiveSheetIndex('.(str_replace('page','',trim($excel_rows[$key])) -1).');<br/>'.PHP_EOL;
//$table_columns[$key] = 0; I'm not sure what this is supposed to do
$subkey++;
}
else {
$excel_row .= '$objTpl->getActiveSheet()->setCellValue(\''.trim($excel_rows[$key]).'\',$row[\''.trim($table_columns[$fieldkey]).'\']);<br/>'.PHP_EOL;
}
}
print $excel_row;

Related

Only show items with a particular criteria in an array

I am trying to show only items that meet a certain criteria in an array. At the moment I am outputting everything in the array.
What I've got so far:
$records = $d->get("FoundCount");
$result = array();
for($i = 1; $ <= $record; $i++){
// various array components
$show_published = $d->field(show_published); //this is the variable from the DB that will determine if the item is shown on the page. Yes/no string.
if($show_published == 'Yes'){
$results[] = new Result(//various array components, $show_published, //more things);
}
This seems to output all items, including the ones labeled as 'No' .
Any guidance would be great. I have only been using php for a few months now.
I'm not sure if you're familiar with composer and how to install / use php packages.
If you are, you can add illuminate/support package as a dependency for your project and use its Collection to filter records - something along the lines of:
use Illuminate\Support\Collection;
$collection = new Collection($records);
$outputArray = $collection->filter(function($object) {
return (string) $object->field('show_published') === 'Yes';
})->toArray();
https://laravel.com/docs/5.5/collections
After this, the $outputArray will contain only records that have show_published flag set to Yes.
Alternatively you could use php's native function array_filter in pretty much the same manner:
$outputArray = array_filter($records, function($object) {
return (string) $object->field('show_published') === 'Yes';
});
http://php.net/manual/en/function.array-filter.php
Here's a simple example on how to create a new filtered array based on the criteria of strings starting with the character 'b'. I'm not sure what your criteria is but you could certainly take this approach and modify it to suit your needs.
//Original array of things that are un-filtered
$oldArray = array("Baseball", "Basketball", "Bear", "Salmon", "Swordfish");
//An empty filtered array that we will populate in the loop below, based on our criteria.
$filteredArray = array();
foreach($oldArray as $arrayValue) {
//Our criteria is to only add strings to our
//filtered array that start with the letter 'B'
if($arrayValue[0] == "B")
{
array_push($filteredArray, $arrayValue);
}
}
//Our filtered array will only display
//our 3 string items that start with the character 'B'
print_r($filteredArray);
Hope it helps! If not, feel free to reach out.

How Can You Reorder And Reorganize Coordinates From A KML File With PHP?

According to http://assemblysys.com/php-point-in-polygon-algorithm/ I can take a group of points that form a polygon and determine whether or not a point resides inside or outside the polygon. I have also created an KML file when is being utilized by JavaScript to determine which points are inside, however my end goal would to have each marker contain an extra data set inside of a MySQL table that will store this data for later use resulting in a quicker map load time.
Looking through the KML file, each Polygon has a set of coordinates that are separated by ",0.0" which means little because according to the above document I only need the set of lats and longs. In addition, the latitudes and longitudes are in different places. Below is an example of the cordinates:
-86.1459875,39.8622513,0.0 -86.1459875,39.8555639,0.0 -86.1398077,39.8556628,0.0 -86.1398077,39.862218399999996,0.0 -86.1459875,39.8622513,0.0
Instead I want the set to look like the following:
39.8622513 -86.1459875, 39.8555639 -86.1459875, 39.8556628 -86.1398077, 39.862218399999996 -86.1398077, 39.8622513 -86.1459875
Below is a sample of my code, however I am not sure if there is an easier way of manipulating the array using PHP without the use of multiple for loops or foreach loops.
$kml = 'document.xml';
//get the total number polygons
$numPoly = count( $kml->Document[0]->Folder);
$newArray = array();
$a = 1;
$explode;
$explode['coordinates'];
for( $i=0; $i <= $numPoly; $i++)
{
$numPlace = count( $kml->Document[0]->Folder[$i]->Placemark); //count the number of placemarks there are
for($z = 0; $z <= $numPlace; $z++)
{
$regionName = $kml->Document[0]->Folder[$i]->Placemark[$z]->name."</br>"; //grab each placemarks name
//get the cordinates inside of each placemark
$regionCords = $kml->Document[0]->Folder[$i]->Placemark[$z]->Polygon->outerBoundaryIs->LinearRing->coordinates;
//print_r($regionCords); print "<br/><br/>";
foreach($regionCords as $num2 => $region)
{
print $a;
$explodeCords = array_splice( explode('|', str_replace(',0.0',' |', $regionCords) ), 0, -1 ) ;
foreach ($explodeCords as $exploded)
{
$exploded = explode(',', $exploded);
$exploded1 = $exploded[0];
$exploded2 = $exploded[1];
$explodedString = $exploded2.$exploded1.",";
//echo $explodedString; echo "<br/><br/>";
}
}
$numCordinates = count($explodeCords['coordinates'] ); //returns the number of [lat,long] cords in each cordinate set
if ( !empty( $regionCords ) )
{
$a++;
}
}
}
Please let me know if I am on the right path or if there is another way you can easily switch these two numbers using mostly array functions with PHP.
A solution: after each foreach loop, it is best practice to remove the new array out of the loop, because if you are to add another foreach loop, unwanted effects may result such as appending a value to a new array in multiples.
After the values are removed from the foreach loop, you can always use a array_map to switch the coordinates. For a more completed example of this please see the following Github repo: https://github.com/jdmagic21/GMapParse

PHP function not running

My page grabs some records from a mssql DB, reads them into an array called $rows, with 3 columns:
ComputerName, Room, time_in_days
From $rows a second array is created (called $graph) with two columns, with the key being time_in_days from $rows, and the value column being a count of how often time_in_days occurred in the first array. The $graph array is used to create a number of HTML divs to give the impression of a graph.
I then want to be able to click on each individual div and using the $key value from the $graphs array, want to look up the rest of the information associated with all records in $rows where $graph[$key] matches $rows['time_in_days'] and display those records on the page.
But I have got stuck! I don't know where to put the function, the if statement(see code below) and at the moment, it doesn't even seem to be running the function. I don't even think I have the function code right. So if you could help with any of that I will very much appreciate it!
This is the code where the divs/graph is created:
foreach($graph as $key => $value){
$width = $value * $factor;
$page .= '<div style="width:40px;display:inline-block;">'.$key.'</div><div class="bar '.$key.'" style="width:'.$width.'px;"></div><div style="display:inline-block;margin-left:2px;">'.$value.'</div><br/>';
}
This is the function so far:
function SearchDays($key, $page, $rows) {
$computers = array();
foreach ($rows as $arr){
if ($key == $arr["time_in_days"]){
$computerName = $arr["ComputerName"];
$computers[$computerName] = $arr;
}
}
$page .= '<p>computers array from function SearchDays(): <pre>'.print_r($computers,true).'</pre></p>';
return;
}
And this is the if statement that makes the if statement that should run the function:
if (isset($_GET['barclick'])){
SearchDays($key, $page, $rows);
}
$page is just a variable that holds everything that is printed out onto the HTML page. The page itself can be seen here: cems.uwe.ac.uk/~s3-gupta/histogram/index.php. The whole page code can be got here: https://www.dropbox.com/s/h2q7x9xxtjbktx9/index.php
Thanks in advance. Please let me know if you need me to clarify things. I try and be as clear as possible on here, but usually don't manage it, so let me know if you need more.

Create PHP array's on the fly

I am having the worst time trying to get this to work. In the following code, I am gathering data from a database query and trying to build a muti-dimensional array object that will keep totals and tally up some information in a specific way. The problem is that instead of getting a value that is incrementing as it should, the value seems to be suffering from the last value it was assigned problem. Here is the code:
$REVIEWS = array();
$USER_REVIEWS = array();
$USER_IMGREVS = array();
pseudo-code: loop here which iterates over the DB results creating
$date - which is into this function as its called for each day of month
$p1user - which is one of the users (there are 3) 'levels' of users
$hr - is the hour which is built from the transaction's timestamp
$hr = date('H', $row['P1TIMESTAMP']);
$p1user = $row['P1USER'];
$REVIEWS[$date] += 1;
$USER_REVIEWS[$date][$p1user][$hr] += 1;
$USER_IMGREVS[$date][$p1user][$hr] += $row['F5'];
print "PASS1<br/>\n";
print "Value of Total Reviews: [".$REVIEWS[$date]."]<br/>\n";
print "Value of User Reviews: [".$USER_REVIEWS[$date][$p1user][$hr]."]<br/>\n";
print "Value of Reviewed Images: [".$USER_IMGREVS[$date][$p1user][$hr]."]<br/>\n";
print "<br/><br/>\n";
So - the 'total reviews' increments by one, as it should, for each time i print this. SO far so good. The next two arrays will only print the last values they were assigned, and will not be added together like they should. Why not? I have attempted to do this another way by literally creating the arrays one by one and assigning them in whole to the array containing them - but that also does not seem to work. Any insights?
i don't know how you initilize your array, maybe this will help:
// replace this 2 lines:
$USER_REVIEWS[$date][$p1user][$hr] += 1;
$USER_IMGREVS[$date][$p1user][$hr] += $row['F5'];
// with this code:
if (!isset($USER_REVIEWS[$date]))
$USER_REVIEWS[$date] = array();
if (!isset($USER_REVIEWS[$date][$p1user]))
$USER_REVIEWS[$date][$p1user] = array();
if (!isset($USER_REVIEWS[$date][$p1user][$hr]))
$USER_REVIEWS[$date][$p1user][$hr] = 0;
$USER_REVIEWS[$date][$p1user][$hr] += 1;
if (!isset($USER_IMGREVS[$date]))
$USER_IMGREVS[$date] = array();
if (!isset($USER_IMGREVS[$date][$p1user]))
$USER_IMGREVS[$date][$p1user] = array();
if (!isset($USER_IMGREVS[$date][$p1user][$hr]))
$USER_IMGREVS[$date][$p1user][$hr] = 0;
$USER_IMGREVS[$date][$p1user][$hr] += $row['F5'];
Sir, I dont understand very well why your coed is not working, but in my first test, I would change these lines:
$count = 1;
$USER_REVIEWS[$count][$p1user][$hr] += 1;
$USER_IMGREVS[$count][$p1user][$hr] += $row['F5'];
$count++;
Please, check if this code helps you anyway.
Your print statements for those values rely on the value of $p1user:
print "Value of User Reviews: [".$USER_REVIEWS[$date][$p1user][$hr]."]<br/>\n";
print "Value of Reviewed Images: [".$USER_IMGREVS[$date][$p1user][$hr]."]<br/>\n";
If you want to print it for all users you should loop over all possible users rather than just using $p1user. Either that or add them up if you want their sum.
Edit: Something that was bugging me was your data structure. It doesn't seem to represent your data very well. In your loop why don't you build up useful information that you store at the base of the review array?

Keeping an array sorted in PHP

I have a PHP script which reads a large CSV and performs certain actions, but only if the "username" field is unique. The CSV is used in more than one script, so changing the input from the CSV to only contain unique usernames is not an option.
The very basic program flow (which I'm wondering about) goes like this:
$allUsernames = array();
while($row = fgetcsv($fp)) {
$username = $row[0];
if (in_array($username, $allUsernames)) continue;
$allUsernames[] = $username;
// process this row
}
Since this CSV could actually be quite large, it's that in_array bit which has got me thinking. The most ideal situation when searching through an array for a member is if it is already sorted, so how would you build up an array from scratch, keeping it in order? Once it is in order, would there be a more efficient way to search it than using in_array(), considering that it probably doesn't know the array is sorted?
Not keeping the array in order, but how about this kind of optimization? I'm guessing isset() for an array key should be faster than in_array() search.
$allUsernames = array();
while($row = fgetcsv($fp)) {
$username = $row[0];
if (isset($allUsernames[$username])) {
continue;
} else {
$allUsernames[$username] = true;
// do stuff
}
}
The way to build up an array from scratch in sorted order is an insertion sort. In PHP-ish pseudocode:
$list = []
for ($element in $elems_to_insert) {
$index = binary_search($element, $list);
insert_into_list($element, $list, $index);
}
Although, it might actually turn out to be faster to just create the array in unsorted order and then use quicksort (PHP's builtin sort functions use quicksort)
And to find an element in a sorted list:
function binary_search($list, $element) {
$start = 0;
$end = count($list);
while ($end - $start > 1) {
$mid = ($start + $end) / 2;
if ($list[$mid] < $element){
$start = $mid;
}
else{
$end = $mid;
}
}
return $end;
}
With this implementation you'd have to test $list[$end] to see if it is the element you want, since if the element isn't in the array, this will find the point where it should be inserted. I did it that way so it'd be consistent with the previous code sample. If you want, you could check $list[$end] === $element in the function itself.
The array type in php is an ordered map (php array type). If you pass in either ints or strings as keys, you will have an ordered map...
Please review item #6 in the above link.
in_array() does not benefit from having a sorted array. PHP just walks along the whole array as if it were a linked list.

Categories