How to sort a table containing csv file data - php

I have to sort the file data in a table depending on how the user chooses it to be sorted (only options are ascending and descending)
Here is my code for it:
if($submit=="Display"){
if ($headings=="0"){echo "<h2>Error</h2>";}
elseif ($search==""){echo "<h2>Error</h2>";}
else {
if($headings==$headings_array[0])
echo "<table border='1'>";
$f = fopen("data.csv", "r");
while ($line = fgetcsv($f)){
echo "<tr>";
foreach ($line as $cell) {
echo "<td><center>".$cell."</center></td>";
}
echo "<tr>";
}
fclose($f);
function my_sort($a, $b){
if ($a == $b) return 0;
return ($a > $b) ? -1 : 1;
}
$arr = $cell;
usort($arr, "my_sort");
print_r ($arr);
echo "</table>";
}
}
But it's not sorting. Can someone spot what's wrong with it? And if you have a more efficient way of doing this, please let me know as I have 15 headings and it would be a pain to do if statements for each of those headings.
To be clear, here is what I have to do:
For each sort field (which are the headings) that the user chooses, I have to arrange the display according to that heading
i.e if($headings==$headings_array[0])
$headings_array[0] is equal to Names therefore, the table should display the values in alphabetical (or reverse alphabetical) order of Names
Extra info:
$headings is the name of the select box
$headings_array is the array values for the select box
$search is the radio buttons containing whether the table should be sorted as ascending or descending
PHP only
Any help is appreciated!

I think your sort function is wrong. It's doing the same thing as sort() or rsort() would do.
usort simply compares two array elements and determines if they need to be swapped based on the value you return. Your sending in $a and $b, which should be csv lines. Then you compare the indexes that you need to and swap the lines accordingly.
You need to have it sort by the array index given by heading. maybe try something like this:
global $headings;
...
$arrayToBeSorted = array();
// send in an array of lines
while ($line = fgetcsv($f)){
$arrayToBeSorted[] = $line;
}
usort($arrayToBeSorted, 'my_sort');
function my_sort($lineA, $lineB){
// set this to the column that needs to be sorted
global $headings;
$linePartsA = explode(',' $lineA);
$linePartsB = explode(',' $lineB);
if ($linePartsA[$headings] == $linePartsB[$heading) return 0;
return ($linePartsA[$headings] > $linePartsB[$heading]) ? -1 : 1;
}
}

Why do you want to use php only . I used jquery table sorter which is very efficient .here is the link table sorter

Related

Get value from multi-dimensional array using variable

I want to get keys and values from a multi-dimensional array dynamically, to better explain what I'm trying to achieve please see the code below.
$i = 0;
foreach ($faq as $f) {
$q = 'faq'.$i;
$a = 'faq'.$i.'_answer';
echo $faq['faq1'][$i];
echo $faq['faq1_answer'][$i];
$i++;
}
The literal text above faq1 and faq1_answer needs to be replaced by the variable $q and $a respectively for me to be able to get the keys and values dynamically, but I cannot figure out how to add the variable.
The keys will always be the same, except for the number, which will change from 1 to 99. So with the code above, I can get the value of faq1 but I also need to grab the value of faq2 etc, hence why the variables above would work as I need.
tl;dr faq1 needs to be able to change to faq2 on the next iteration, hence the reason for me using $i.
Maybe like this?
$i = 0;
foreach ($faq as $f) {
$q = 'faq'.$i;
$a = 'faq'.$i.'_answer';
echo $f[$a];
echo $f[$a];
$i++;
}

Combining two seperate arrays each with a different number of elements

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;

Sort php array inside loop by number

<?php
foreach ($jsonObj as $items) {
foreach ($items["items"] as $itemlist){
// $itemlist['position']; I want them to echo in that order
echo $itemlist['name'];
}
}
?>
I have an array that I loop through. In that array there is name and order. I would like to display them in numerical order, how can I make it print out the itemlist with lowest number first, then the second etc?
You can use usort with cmp_function for this. Try this function:
function compare_position($a, $b) {
return $a['position'] - $b['position'];
}
Then when you are iterating through the array:
foreach ($jsonObj as $items) {
usort($items['items'], "compare_position");
foreach ($items["items"] as $itemlist){
echo $itemlist['position'];
echo $itemlist['name'];
}
}
More about usort can be found here http://php.net/manual/en/function.usort.php
Hope this helps :)
You need to prepare an array of the positions to sort on first. Sort then sorts by reference allowing you to loop through it a second time but this time as sorted by array_multisort().
<?php
foreach($jsonObj as $items) {
foreach($items['items'] as $key => $itemlist) {
$positions[$key] = $itemlist['position'];
$names[$key] = $itemlist['name'];
}
array_multisort($positions, SORT_ASC, $items['items']);
foreach($items['items'] as $itemlist) {
echo $itemlist['name'], "<br />";
// Now in asc order of positions
}
}
The advantage of this is if other attributes come along that you want to sort on you can do that. For example if there's a chance 'position' will be the same for two people, you could then sort alphabetically by their name etc..
Full solution on Codepad, two answers compared:
http://codepad.viper-7.com/5yJ72S

custom order and display foreach PHP

Thanks to the many folks who help us out here on Stackoverflow. You all are awesome! Now to the question. I've got an array for the following values: "duck", "chicken","egg", "pork", "steak", "beef", "fish", "shrimp", "deer", and "lamb."
I've gotten the list to display in Alphabetical order. This is a dynamic array, so it may not always have all these values or be in that order. I'd like to have "Steak" always appear first with "Top Choice" next to it, while keeping the rest in alphabetical order with "Available for Order" next to them.
Here's what I've got thus far with $meat_items as the array:
foreach($meat_items as $meat_item)
echo $meat_item . ' Available for Order <br>';
I should clarify: Steak may NOT always be a part of the array.
Since you always want steak to appear first, hard code it:
if (in_array("steak", $meat_items)) {
`echo "Steak: Top Choice";`
}
Sort your array alphabetically:
sort($meat_items);
Then loop through your array, echoing all items except the steak:
foreach ($meat_items as $meat_item) {
if ( "steak" != $meat_item ) {
echo $meat_item . ' Available for Order<br />';
}
}
if (!empty($meat_items['steak']))
{
echo 'Steak Top Choice <br >';
unset($meat_items['steak']);
}
sort($meat_items);
foreach($meat_items as $meat_item)
echo $meat_item . ' Available for Order <br>';
A more general purpose way to do this is to tell PHP how to sort the items, by defining a sorting "comparison" that prefers the "top choices", and then passing it to usort.
I don't really know PHP, but something like:
function prefer_top($a, $b) {
/* We can modify this array to specify whatever the top choices are. */
$top_choices = array('Steak');
/* If one of the two things we're comparing is a top choice and the other isn't,
then it comes first automatically. Otherwise, we sort them alphabetically. */
$a_top = in_array($a, $top_choices);
$b_top = in_array($b, $top_choices);
if ($a_top && !$b_top) { return -1; }
if ($b_top && !$a_top) { return 1; }
if ($a == $b) { return 0; }
return ($a < $b) ? -1 : 1;
}
usort($meat_items, "prefer_top");
// and then output them all in order as before.

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