11

I'm trying to break a PHP array into 3 columns (has to be columns, not rows) so it would look something like this:

Item 1     Item 2     Item 3
Item 4     Item 5     Item 6
Item 7     Item 8     Item 9
Item 10................

The best approach I can think of would be to break the main array into 3 arrays, 1 for each column although I can't work out the best approach to do this - more specifically the criteria I could use to generate the 3 arrays.

6
  • How should the items be ordered within these columns? (should it be 123,456,789 or 147,258,369) Commented Jan 2, 2012 at 1:42
  • 1
    "Has to be columns, not rows"...? But you are showing rows of data in your example...? Commented Jan 2, 2012 at 1:51
  • @deceze imagine the data in three divs, 1 for each column. That isn't rows. Commented Jan 2, 2012 at 22:28
  • With the data you're showing it hardly makes a difference. A regular table view could do. What exactly do you want to achieve? Why is it important to think of the data in columns, not rows of 3 columns? Why does one column need to be one <div>? Why does it need to be a <div> and why didn't you specify this in the question? Commented Jan 3, 2012 at 0:56
  • @deceze It needs to be columns, not rows as what I'm trying to display is images of equal widths but indeterminate heights. The idea is that they will display in order across the rows, but so that the gaps between each image vertically is always equal, they will be grouped by columns. The fact that I didn't specify that it needs to be in <divs> is irrelevant as I had already explained that it needs to be in columns, not rows. Commented Jan 3, 2012 at 9:53

7 Answers 7

8

I would use this:

$i = 1;
foreach ($array as $value) {
  if ($i % 3 === 0) {
        echo $value . '<br />';
    }
   $i++;
}

Or when using html table:

<table>
<tr>
   <?php 
   $i = 0;
   foreach ($array as $value) {
      if ($i % 3 === 0) {
            echo '</tr><tr>';
        }
      echo "<td>" . $value . "</td>";
      $i++;
   }
   ?>
</tr>
</table>
Sign up to request clarification or add additional context in comments.

2 Comments

For me, I had to check if the $i != 0 together with the $i % 3 == 0 . (Using === didn't worked). But thanks for your help.
Big time saver, this one! Just installed it on a site with heavy jQuery behind it, and this solution makes over 3,000 people (on a polling page) very happy the coming month.
3

You can use array_slice to extract a section of an array, so:

$newArray = array();

for($i = 0; $i < count($oldArray); $i += 3) {
    $newArray[] = array_slice($oldArray, $i, 3);
}

Edit: As @deceze points out, this does the same thing as array_chunk. (I knew PHP would have something built-in.) So use that instead!

18 Comments

Although this shows how to split the array, it doesnt solve the OP's problem.
@deceze: That's an answer. But yes I am ;)
The question is how can i output my array in 3 columns, not how can i split it in 3 different arrays. It is a suggestion on how to solve it, and not an optimal one imho.
This is not what he wants. He wants 1, 4, 7 and 10 in the first column.
This seems like a reasonable approach although the idea was that the arrays would contain non-consecutive elements, at positions (1,4,7)(2,5,8) & (3,6,9) etc.
|
2
$data = array(); 
$columns = 3;

echo "<table><tr>";

for($i = 0; $i < count($data); $i++)
{
 if($i%$columns == 0)
  echo "</tr><tr>";
 echo "<td>".$data[i$]."</td>";
}
echo "</tr></table>";

There you go, it just outputs another row when you get to your column count. You might need to add some logic when the data isnt a multiple of 3.

Comments

2

Using array_chunk you can split array :

$rows = array_chunk($yourArray, '3'); // 3 = column count;
foreach ($rows as $columns) {
    echo "<div class='row'>";
    foreach ($columns as $column) { 
        echo "<div class='column'>$column</div>"; 
    }
    echo "</div>";
}

1 Comment

Unfortunately array_chunk does not split them in the order specified in the question. It will put 1,2,3 in the first column. I wish array_chunk had a option to distribute them left to right.
1

When considering your question topic it's first impression is"Column" and I think you needed to focus on visual aspects. "How to display your array as three columns" May be my idea is wrong. But I think you wanted that. Just check following example if my thought is correct.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>

</head>
<?php
$arr = array(1,2,3,4,5,6,7,8,9,10);
?>
<body>
<div style="width:300px">
<ul>
    <?php foreach($arr as $itm) {?>
    <li style="list-style:none;float:left;width:80px;"><span style="font-size:36px;"><?php echo $itm;?></span></li>
    <?php }?>
</ul>
</div>
</body>
</html>

7 Comments

Wouldn't this just display the array as a single column?
No. These three columns control with CSS. You don't need to do that programmatically. It's just uses width & float CSS attributes with un-ordered list.
This again would effectively produce rows - for what I need, columns are the only way it will work.
This is absolutely the best way to do it, unless there is some unmentioned reason why you can't use divs and floats. The advantages of this have been written about ad nauseum, but basically, it is more flexible, maintainable, accessible, better for SEO, and more besides.
@pspahn. Have you checked this? This code produce 3 columns as he need since the width of the dive is 300px and list item width is 80px.
|
1

Having just thought about it, this should achieve what I want - whether it's the fastest method though, I'm not sure:

$array = (1,2,3,4,5,6,7,8,9....)


$column1 = array();
    $i = 2;

foreach($array as $value) {
    if ($i++ % 3 == 0) {
        $column1[] = $value;
    }
}


$column2 = array();
    $i = 1;

foreach($array as $value) {
    if ($i++ % 3 == 0) {
        $column2[] = $value;
    }
}

$column3 = array();
    $i = 0;

foreach($array as $value) {
    if ($i++ % 3 == 0) {
        $column3[] = $value;
    }
}

EDIT: The same as above although using a single foreach loop:

$array = (1,2,3,4,5,6,7,8,9....)


    $column1 = array();
    $column2 = array();
    $column3 = array();
    $i = 2;
    $j = 1;
    $k = 0;


foreach($array as $value) {
    if ($i++ % 3 == 0) {
        $column1[] = $value;
    }
    if ($j++ % 3 == 0) {
        $column2[] = $value;
    }
    if ($k++ % 3 == 0) {
        $column3[] = $value;
    }
}

2 Comments

Please see my answer as it outputs the data in different columns, just as you suggested. You dont need to store it in different arrays, you can just start a new row after each Nth element.
@TJHeuvel Although in three columns, does this not ultimately return the results in rows? I need the results returned in three separate divs.
1
header('Content-Type: text/plain');

echo '<table>';

$colNum = 3;
$regNum = 10;

for ($i = 1; $i <= $regNum; $i++) {

    if (($i % $colNum) == 1) {

        echo "\n\t".'<tr>';

    }

    echo "\n\t\t".'<td>'. $i .'</td>';

    if (($i % $colNum) == 0 or $regNum <= $i) {

        echo "\n\t".'</tr>';

    }

}

echo "\n".'</table>';

Comments

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.