Search code examples
phpmultidimensional-arraypaginationpaginator

Algorithm to separate pagination display by ...?


Have an $A is the data for pagination:

   $A = array(
      0=>array(
          0=>1,
          1=>2
          ),
      1=>array(
          0=>3,
          1=>5,
          2=>2
        ),
      2=>array(
          0=>3,
          1=>1,
          2=>6,
          3=>6
          )
      );

Anybody could help me to get the expected ouput (output this "...." more) the most important ?

.... told that it is still more element need to display next page. or it the remain element from previous page.

There are 09 elements of $A to display ,So

I set

$show_per_page = 3;

Output (for the first page):

  1 
  2
Total:3
  3
 ....//output this "...."  more 

Output (for the second page):

....//output this "...." continue from first page 
  5
  2
Total:10
  3
.... //output this "...." more

Output (for the third page):

 .... //output this "...." continue from  second page
    1
    6
    6
    Total:16

if I set

$show_per_page = 5;

Output (for the first page):

1
2
Total:3
3
5
2
Total:10
// .... //not output this "...." more now 

Output (for the second page):

3
1
6
6
Total:16

if I set

$show_per_page = 9;

OUTPUT:

        1
        2
      Total:3         
         3
         5
         2
      Total:10
         3
         1
         6
         6
     Total:16

Currently I am try to do with the function paging_from_multi_arr but I am stuck on how implement to got the expeted result:

// page to show (1-indexed)
// number of items to show per page
function paging_from_multi_arr($display_array, $page){
    Global $show_per_page;
    $start = $show_per_page * ($page-1);
    $end   = $show_per_page * $page;
    $i = 0;
    foreach($display_array as $main_order=>$section){
        $total = 0;
        foreach($section as $sub_order=>$value){
            if($i >= $end){
                break 2; // break out of both loops
            }

            $total += $value;
            if($i >= $start){
                echo $value.'<br>';
            }
            $i++;
        }
        if($i >= $start){
            echo 'Total:'.$total.'<br>';
        }
        if($i >= $end){
            break;
        }
    }
    $total = count($display_array, COUNT_RECURSIVE);
    // Total numbers of elements in $display_array array.
    // See http://php.net/manual/en/function.count.php
    if ($end < $total){
        echo "...";
    }
}


$show_per_page = 5;
paging_from_multi_arr($A,$_GET["page"]);

Do you have any idea with the function here? Or could give the better algorithm?

thanks


Solution

  • This should give you the output you're looking for:

    function flatten_display_array($display_array){
        $new_array = array();
        $count = 0;
    
        foreach($display_array as $main_order => $section){
            $total  = 0;
            foreach($section as $sub_order => $value){
                $new_array[] = array('main'  => $main_order,
                                     'sub'      => $sub_order,
                                     'value'    => $value);
                $total += $value;
                $count++;
            }
            // Add section's total to final element in section
            $new_array[$count-1]['total']   = $total;
        }
    
        return $new_array;
    }
    
    function paging_from_multi_array($display_array, $page = 1, $show_per_page = 3){
        if(isset($_GET['page']) && is_numeric($_GET['page'])){
            // Page number set externally
            $page = $_GET['page'];
        }
        if(isset($_GET['per_page']) && is_numeric($_GET['per_page'])){
            // Per page set externally
            $show_per_page  = $_GET['per_page'];
        }
    
        $start  = $show_per_page*($page-1);
        $end    = $show_per_page*$page;
    
        // Convert array to useable format
        $new_array = flatten_display_array($display_array);
    
        /* Formatting elements */
        $top_string = '....';   // Indicator continues is on previous page
        $bottom_string  = '....';   // Indicator continues on next page
        $br         = '<br />';     // Line break
        $indent     = '&nbsp;&nbsp;&nbsp;'; // Indent of value row
    
        $count  = 0;
        $string = '';
    
        for($i = $start; $i < $end; $i++){
            // Loop through visible range
            $string .= $indent.$new_array[$i]['value'].$br;
            if(isset($new_array[$i]['total'])){
                $string .= 'Total: '.$new_array[$i]['total'].$br;
            }
        }
    
        // Check previous page
        if($start > 0 && $start < count($new_array) && !isset($new_array[$start-1]['total'])){
            // Started mid-way through section
            $string = $top_string.$br.$string;
        }
    
        // Check next page
        if($end-1 < count($new_array) && !isset($new_array[$end-1]['total'])){
            // Stopped mid-way through section
            $string .= $bottom_string.$br;
        }
    
        return $string;
    }
    

    To use it, just call the paging_from_multi_array() function:

    echo paging_from_multi_array($A);
    

    This way, if the page number or the amount to show per page is not set, it will default to the ones set in the first line of paging_from_multi_array() (currently page 1 and 3 per page).

    Also, look at the lines under /* Formatting Elements */ to set the elements for the output (eg: the '...' before and after each segment.