0

I have an array of objects which i would like to output in 3 group by a specified order. Right now my output groups the data after every 3 element but sadly thats good anymore. So now I need to group it in this order:

1 group: 1, 4, 7, 10, ... and so on

2 group: 2, 5, 8, 11, ... and so on

3 group: 3, 6, 9, 12, ... and so on

but I couldn't figure out how.

Until now I did it like this:

<?php
$group=3;
$count = (count($this->data));
$i=0;
foreach($this->data as $key => &$result){
  $row = ( ((int)$key) % (int)$group)+1;
  if($row==1){
    echo '<div class="row">';
  }
  echo '<div class="item-'.($i+1).'">';
  /*echoing a lots of stuf*/
  echo '</div>';
  $i++;
  if($row == $group || $i == $count){
    echo '<hr />';
    echo '</div>';
  }
}
?>

but as I wrote before this is not good anymore

if my question isn't clear than here is my desired html output:

<div class="row">
  <div class="item-1"></div>
  <div class="item-4"></div>
  <div class="item-7"></div>
  <div class="item-10"></div>
</div>
<div class="row">
  <div class="item-2"></div>
  <div class="item-5"></div>
  <div class="item-8"></div>
  <div class="item-11"></div>
</div>
<div class="row">
  <div class="item-3"></div>
  <div class="item-6"></div>
  <div class="item-9"></div>
  <div class="item-12"></div>
</div>

Is this even possible?

3 Answers 3

2

Now that I really know what you want, you can do it like this:

$group = 3;

$length = count( $this->data );
$matrix = array();
for ( $i = 0, $row_n = 0; $i < $length; ++$i, $row_n++ ) {
    // Reset row.
    if ( $row_n === $group ) {
        $row_n = 0;
    }

    // Set cell.
    $row =& $matrix[$row_n];
    $row[] = 0;

    // Find column nr.
    end( $row );
    $cell_n = key( $row );

    // Update with correct key nr.
    $key = $row_n + $cell_n * $group;
    $row[$cell_n] = $key;
}

/*
echo "<pre>";
print_r( $matrix );
echo "</pre>";
*/

foreach ( $matrix as $row_n => $row ) {
    echo "\n<div class='row'>";

    foreach ( $row as $cell_n => $key ) {
        echo "\n\t<div class='item-". ($key + 1) ."'>";

        echo $this->data[$key];

        echo "\n\t</div>";
    }

    echo "\n</div>";
}
Sign up to request clarification or add additional context in comments.

1 Comment

You are my saviour! Thank you!
0

If you want to do it straight forward, just split origin array into how many groups you want, and then use the new, re-sorted array to printing out HTML.

$a = array(1,2,3,4,5,6,7,8,9,10,11,12);

$array = array();
$group = 3; // <--- how many groups you want

$pointer = 0; //init pointer to first group
foreach($a as $value) {
    if($pointer == $group) $pointer = 0; // reset pointer
    $array[$pointer][] = $value; // two detention array have groups -> items
    $pointer++;
}

//use new sorted array print HTMl
foreach($array as $classRow) {
    echo "<div class='row'>";
    foreach($classRow as $item) {
        echo "<div class='item-".$item."'></div>";  
    }
    echo "</div>";
} 

2 Comments

Maybe I'm dumb but I don't see how it solves the ordering. As I see whit this methode I would output the groups in same order as they are in the $a array so I would end up whit this: group1: 1,2,3,4 group2: 5,6,7,8 group3: 9,10,11,12
By using the logic: $row_n + $item_n * $group, same as I did in the code I provided. @VVLeon:s method is cleaner than mine - but is a more obvious mechanism ;)
0

You could try something like this:

$data = array(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18);

$groups = 3;
$items_per_group = count($data) / $groups;
$i     = 0;
$item  = 0;
$row   = 0;
$open = false;

foreach ( $data as $key => &$result ) {
    if ( $i % $items_per_group === 0 ) {
        $row++;
        $item = 0;

        if ( $open ) {
            echo "\n</div>";
        }

        echo "\n<div class=\"row\">";
        $open = true;
    }

    $nr = $row + $item * $groups;
    echo "\n\t<div class=\"item-$nr\">";
    // echoing a lots of stuf
    echo "\n\t</div>";

    $item++;
    $i++;
}

if ( $open ) {
    echo "\n</div>";
}

Might be some error in there, but I hope you get the gist ;)

7 Comments

hm this outputs like this for me <div class="row"><div class="row"><div class="row"></div></div></div>
That shouldn't be possible... at least it should print out some <div class="item-... s
oh it prints out <div class="item"> I just shortend the code because i didn't wanted to put long code into the comment section, but basicly it puts the next row inside the previous row
Can you print out an exact pastebin or something?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.