Así que tengo un problema lógico aquí.

Lo que quiero:

Recorrer un conjunto (en realidad un objeto predecible) si es el primer elemento echo a <div>, entonces cada tres elementos hacen eco al cierre </div>.

Si hay menos de 3, por supuesto, finalice el div también. EDITAR: como no estaba claro, lo que quiero lograr se basa en n ° de elementos. Paradójicamente, también necesito que funcione con 0 elementos.

0 elementos:

<div><div>

1 elemento:

 <div>
   <a></a>
 </div>

3 elementos:

 <div>
      <a></a>
      <a></a>
      <a></a>
 </div>

5 elementos:

    <div>
      <a></a>
      <a></a>
      <a></a>
    </div>
    <div>
      <a></a>
      <a></a>
    </div>

Etc ..... entendiste

Mi código equivocado:

        $counter = 0;
        foreach ($prods as $prod) {
            if($counter == 0 || ($counter % 3) == 0) {
                $htm_l .= '<div data-count="' . $counter . '">';  //just keeping track
            }
            $htm_l .= '<a data-id="' . $prod->id . '"> link </a>';

            $counter++;

            if($counter == 0 || ($counter % 3) == 0) {
                $htm_l .= '</div>';
            }               
        }
        $counter = 0;
        if($counter == 0 || ($counter % 3) == 0) {
            $htm_l .= '</div>';
        } 

¿Que puedo hacer? (Prod es solo una colección de objetos, podría ser una serie de cadenas)

0
Luca Calabrese 18 oct. 2017 a las 18:55

3 respuestas

La mejor respuesta

Este es un código no probado pero debería funcionar para usted a menos que tenga el caso especial de un objeto de productos vacío y no desee que se produzca un div vacío. Eso requerirá una solución un poco más compleja

$counter = 0;
// start the first div
$htm_l = '<div data-count="' . $counter . '">';
foreach ($prods as $prod) {
    $counter++;
    // close the current div and open a new one after 3 objects
    if ($counter % 3 == 0) {
        $htm_l .= '</div> <div data-count="' . $counter . '">';
    }
    // add the object specific data
    $htm_l .= '<a data-id="' . $prod->id . '"> link </a>';
}
// close the last div
$htm_l .= '</div>';

Para manejar ese caso especial, podría hacer algo como esto.

$counter = 0;
// find out how many total objects we will be stepping through
$total_count = count($prods);
$htm_l = '';
foreach ($prods as $prod) {
    $counter++;
    // always start with a div for the first of 3 objects
    if ($counter % 3 == 1) {
        $htm_l .= '<div data-count="' . $counter . '">';
    }
    // add the object specific data
    $htm_l .= '<a data-id="' . $prod->id . '"> link </a>';
    // close the div after 3 objects or after the last object
    if ($counter % 3 == 0 || $counter == $total_count) {
        $htm_l .= '</div>';
    }
}
1
Perl Guy 18 oct. 2017 a las 16:47

Pruebe lo siguiente:

$counter = 1;
$total = count($prods);
$htm_l = '';
$htm_l .= "<div data-count=\"1\">\r\n";
foreach ($prods as $prod)
{
    $prod->id = $counter;

    $htm_l .= "<a data-id=\"{$prod->id}\"> link </a>\r\n";


    if (($counter % 3) == 0)
    {
        $htm_l .= "</div>\r\n";
    }
    if($counter == $total){$counter++;continue;}
    if (($counter % 3) == 0)
    {
        $htm_l .= "<div data-count=\"$counter\">\r\n";
    }

    $counter++;
}
if (($counter % 3) == 0)
{
    $htm_l .= '</div>';
}

echo($htm_l);

Esto iterará sobre $prods y agregará <div> después de cada 3 <a> etiquetas.

0
mega6382 18 oct. 2017 a las 16:26

Desea comenzar incondicionalmente con un <div> y terminar con un </div>. La única condición es cuándo cerrar / abrir durante el ciclo. Entonces algo como esto debería funcionar:

$counter = 0;
$htm_l   = '<div data-count="0">';

foreach ( $prods as $prod ) {
    $htm_l .= '<a data-id="' . $prod->id . '"> link </a>';

    $counter++;

    if ( $counter % 3 == 0 ) {
        $htm_l .= '</div>';

        if ( $counter != count( $prods )) {
            $htm_l .= "<div data-count=\"$counter\">";
        }
    }
}

if ( $counter % 3 ) {
    $htm_l .= '</div>';
}
0
Nick Coons 18 oct. 2017 a las 16:17