简体   繁体   中英

Output foreach-item in <div>, but output every 2nd and 3rd item in wrapping div

I have an array with items: $array = ['item 1','item 2','item 3','item 4','item 5','item 6','item 7']

I am looking for the following HTML:

<div class="big">Item 1</div>
<div>
    <div class="small">Item 2</div>
    <div class="small">Item 3</div>
</div>
<div class="big">Item 4</div>
<div>
    <div class="small">Item 5</div>
    <div class="small">Item 6</div>
</div>
<div class="big">Item 7</div>

In text: Every 3rd item (including the first) have to have their own div , while the 2nd and 3rd items get a wrapping div .

I've come up with the following loop, but I'm pretty sure it's not going to work in the long run, since it'll probably end the loop with an opening div , since I keep on opening a new one after each BIG ITEM.

$i = 0;
foreach($array as $item) {
    <?php
    if($i % 3 == 0) {
        if($i == 0) {?>
            <div class="big">
                Item <?= $i; ?>
                
            </div>
            <div>
        <?php } else { ?>
            </div>
            <div class="big">
                Item <?= $i; ?>
            </div>
            <div>
        <?php } ?>
    <?php } else { ?>
        <div class="small">
            small item
            <?= $i; ?>
        </div>
    <?php } ?>
<?php 
    $i++;
}

I feel like I'm close, but it also feels wrong to start and close divs in $i s where it doesn't belong. Maybe the only thing I'm missing is checking if $i equals the length of the array, and then don't open a new <div> after a big item?

Alternatively, use array_chunk then pick out the first item with array_shift, then join the remaining.

<?php
$array = array_chunk(['item 1','item 2','item 3','item 4','item 5','item 6','item 7'], 3);

foreach ($array as $set) {
    echo '<div class="big">'.array_shift($set).'</div>';
    if (count($set)) echo '<div><div class="small">'.implode('</div><div class="small">', $set).'</div></div>';
}
?>

Result

<div class="big">item 1</div>
<div>
    <div class="small">item 2</div>
    <div class="small">item 3</div>
</div>
<div class="big">item 4</div>
<div>
    <div class="small">item 5</div>
    <div class="small">item 6</div>
</div>
<div class="big">item 7</div>

Example: https://3v4l.org/URB3D

You can use simple if-elseif-else construct to print the divs.

  • If the index of the current element % 3 is 0, it is a big div, else it is a small div.

  • If the index of the current element % 3 is greater than 0, it is a small div.

    • If it is 1, prepend an opening div tag.
    • If it is 2, append a closing div tag.

Snippet:

<?php

foreach ($array as $idx => $set) {
    $mod = $idx % 3;
    if($mod === 0){
        echo "<div class='big'>$set</div>";
    }elseif($mod === 1){
        echo "<div><div class='small'>$set</div>";
    }else{// if $mod is 2
        echo "<div class='small'>$set</div></div>";
    }
}

Online Demo

Here you are my simple answer: I think you don't need to use additional counter in case that interpreter adds indexes to array:

$array = ['item 1','item 2','item 3','item 4','item 5','item 6','item 7'];
foreach($array as $key=>$da){
$a = $key % 3;
if($a === 0){
    echo "<div class=\"big\">" . $da . "</div>\n";
} 
else{
    if($a === 1)
        echo "<div>\n";
    echo "    <div class=\"small\">" . $da . "</div>\n";
    if($a === 2)
        echo "<div>\n";
}

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM