Grouping results from array by page number.

learning_brain

New Member
Messages
206
Reaction score
1
Points
0
You all know the old problem... 1000's of results and 1 html page...

This is easily resolved if my results were direct from a MySQL result, using LIMIT, but I can't do that....

My results are contrived from a full MySQL result, scoring each result relevance to the search string/s and adding to an array with the relevance value. This is then sorted by relevance and echo'd from the array.

I want to split the results into page sets, using array_slice($array,$startRow,$endRow), and then use a seperate navigation link with the desired page number which will pass a page number to the url....which is almost there but not quite...

I also have an additional problem. I don't think I can use foreach because I need to specify each row number in incremental order to achieve this.

So.....this is where I am now..

PHP:
<?php if(isset($processed_array)){
    
            $maxRows = 18;//specify total rows per page
            $pageNum = 0;//initiate page number
            if (isset($_GET['pageNum'])) {//if page number exists in url
                  $pageNum = $_GET['pageNum'];//page number is the number in url
            }
            $startRow = $pageNum * $maxRows;// start record on specified page is page number times max rows per page
            $endRow = $startRow + $maxRows;
            $totalPages = ceil($count_processed_array / $maxRows);
            
            //split into page sets
            $part_processed_array = array_slice($processed_array, $startRow, $endRow);
            
            $count_part_processed_array = count($part_processed_array);
        
            
           
            for ($row = $startRow;$row < $endRow; $row++) {
            ?>
            
                <echo results from $part_processed_array)......>

            <?php
            }
            
        } else {
        
            echo "<hr/>No Results";
        
        }//end if(isset($processed_array)){

The pageNum and startRow work a treat but the endRow is always startRow + whatever the rows per page is.....which is wrong. I can't get my head round how to manage this if,say, there are 45 result rows on a page of e.g. 50 loops.

I'm also not sure my totalPages is right... :S
 
Last edited:

misson

Community Paragon
Community Support
Messages
2,572
Reaction score
72
Points
48
I also have an additional problem. I don't think I can use foreach because I need to specify each row number in incremental order to achieve this.
Though foreach only handles entire arrays, you can combine it with array_slice as you do and you can process a single section of an array just fine.

PHP:
foreach (array_slice($items, $startRow, $rowsPerPage) as $i => $item) {
  $rowNum = $i+$startRow;
  ...
}
Note: the name $maxRows is misleading; $rowsPerPage is more accurate. Also, array_slice takes the offset & length of the slice, not start & end. Third, array_slice doesn't preserve indices, though this may not matter for your code.

Of course, there's nothing wrong with using a for loop rather than a foreach loop. Personally, I prefer for in cases like this, as it's readable and the array_slice will use more memory.

The pageNum and startRow work a treat but the endRow is always startRow + whatever the rows per page is.....which is wrong. I can't get my head round how to manage this if,say, there are 45 result rows on a page of e.g. 50 loops.
I'm not sure of the problem you're facing. With array_slice, it shouldn't matter if there aren't enough items in the array to produce the requested length; it will simply stop at the end. array_slice(range(0,10), 5, 100); will give you range(5,10). Outside of array_slice, you can use min() to set the upper bound:
PHP:
$fromRow = $startPage * $rowsPerPage;
$upto = min($fromRow + $rowsPerPage, count($rows));
for ($i=$fromRow; $i < $upto; ++$i) {
    ...
}

I'm also not sure my totalPages is right... :S
Then test it. In general, figuring out all the important edge cases to test can take some work, but here testing 0, 10, 20 and 30 results at 20 results per page should be sufficient.


Considering your search implementation, you should cache search results so you don't need to re-run the search for every page of results.
 
Last edited:

learning_brain

New Member
Messages
206
Reaction score
1
Points
0
Perfect - solved it now.

I had two problems. First, the array_slice can preserve indices.. e.g. array_slice($array, $startRow, $pageRows, true); problem solved.

My second was the stupid misunderstanding that the slice uses start/stop, as opposed to your suggestion of start, length.

The for loop was giving me a problem becasue it was always looping through the $pageRows amount, which was always fixed. I have changed this now to counting the amount of rows in each sliced portion.

I've also managed to create a page navigation with the same system..... sweet!

This has made my day!
 
Last edited:
Top