Schleife mit umschließenden Elementen alle 'n' Schritte

2505
Donovan

Ich liste Elemente mit einem auf foreach, und ich möchte Elemente in etwas Tag einschließen, nindem n:

$i = 0;
$open = $done = TRUE;
$n = 3;
$opening = "<div>";
$closing = "</div>";
$names = array("Doc", "Marty", "George", "Lorraine", "Einstein", "Biff"); 

foreach($names as $name) { /** $condition was not a bool. My fault. */

    if($open && !($i % n)) {
        print $opening;
        $open = FALSE;
        $done = !$open;
    } elseif(!($i % n)) $done = FALSE;

    /** print element. */
    print $name;

    if(!$open && !($i % n) && !$done) {
        print $closing;
        $open = TRUE;
        $done = !$open;
    }

    $i++;

}

Denken Sie, dass dieses Snippet verbessert werden kann? Es wäre besser, weniger Prüfvariablen wie $openoder zu haben $done.

Antworten
7
@Albert Kannst du auch hinzufügen, was n und die Bedingung repräsentieren soll? Bekommt es seinen Wert von einem anderen Teil des Codes? greatwolf vor 10 Jahren 1
Können Sie uns ein Arbeitsbeispiel geben? (Ohne Parserfehler). Von seinem gegenwärtigen Zustand habe ich so gut wie keine Ahnung, dass Code vorgeht (oder zumindest ist es nichts, was ich denke, ich kann Apon auf sinnvolle Weise verbessern). Ich bin offen und fertig sind PHP-Variablen? ($ zeichen?) edorian vor 10 Jahren 3
Es tut mir sehr leid. Ich habe die Frage aktualisiert. Donovan vor 10 Jahren 1
`} elseif (! (i% n)) done = FALSE;` ist nicht PHP! `} elseif (! ($ i% $ n)) $ done = FALSE;` ist eine Aufgabe für StackOverflow es kann verbessert werden RobertPitt vor 10 Jahren 2
Ich öffne und schließe immer noch die $ -Zeichen, ich kann es selbst nicht bearbeiten (und ich möchte nicht nur eine Frage dazu stellen.) Danke für die Bearbeitung! Viel klarer jetzt. edorian vor 10 Jahren 1
Könnten Sie uns näher erläutern, was diese Methode tun soll? Es könnte Menschen helfen, die versuchen, es zu verbessern. Sind $ i und $ n magische Zahlen? adamk vor 10 Jahren 0
@Alberteddu, Bitte nur Arbeitscode zur Überprüfung einreichen. Ihr Code wird nicht ausgeführt, da Sie einige $ am Anfang einiger Variablen nicht finden. systemovich vor 9 Jahren 0

2 Antworten auf die Frage

9
sepp2k

Ein Problem bei Ihrer Lösung ist, dass das letzte schließende </div>Tag nicht gedruckt wird, wenn weniger $nElemente als das letzte enthalten <div>.

Ein Ansatz, der dieses Problem behebt und außerdem die bedingte Logik für die Entscheidung, wann die Tags gedruckt werden sollen, vereinfacht, besteht darin, das Array zuerst zu verwenden, array_chunkund dann die Blöcke zu durchlaufen. Jetzt brauchen wir nur noch eine boolesche Variable, um uns zu merken, welche Abschnitte in Tags eingeschlossen werden.

function alternate($names, $n, $opening, $closing) {
    $tag = TRUE;
    foreach(array_chunk($names, $n) as $chunk) {
        if($tag) {
            print $opening;
        }
        foreach($chunk as $name) {
            print $name;
        }
        if($tag) {
            print $closing;
        }
        $tag = !$tag;
    }
}
3
cabbey

Alternative Lösung ohne den Overhead des Aufrufs array_chunk. (Versteht mich nicht falsch, ich liebe array_chunk und benutze es für viele Dinge, aber dies ist nicht einer, wo es gebraucht wird.)

$array = getData(...);
$n = 5; //or whatever you want to chunk into
echo "<div>"; //always open one
$lcv = 1; // loop count variable
foreach ($array as $key => $val) {
    //format $key/$val as needed here...
    if ($lcv++ % $n == 0) { //every Nth item
        echo "</div><div>"; //close old one and open new one
    }
}
echo "</div>"; //always close the last one.

Der schlimmste Fall ist, dass Sie <div></div>am Ende einen leeren Block haben könnten, wenn Sie ein genaues Vielfaches von n hätten. Dies ist jedoch in 99,999% der Fälle kein wirklich großer Deal. :) Wenn es ... dann kann man es so fangen:

$array = getData(...);
$num = count($array);
$n = 5; //or whatever you want to chunk into
echo "<div>"; //always open one
$lcv = 1; // loop count variable
foreach ($array as $key => $val) {
    //format $key/$val as needed here...
    if ($lcv++ % $n == 0 && $lcv < $num) { // every Nth item, unless we're done
        echo "</div><div>"; //close old one and open new one
    }
}
echo "</div>"; //always close the last one.

(Natürlich können Sie verwenden können print, echooder ?>...<?Tags ... was auch immer Sie eigentlich die ganze Ausgabe tun wollen, keine Rolle spielt.)

Und um ehrlich zu sein, würde ich wahrscheinlich noch einen Fall hinzufügen:

$array = getData(...);
$num = count($array);
if ($num == 0) {
    echo "<div>No results?</div>";
} else {
    $n = 5; //or whatever you want to chunk into
    echo "<div>"; //always open one
    $lcv = 1; // loop count variable
    foreach ($array as $key => $val) {
        //format $key/$val as needed here...
        if ($lcv++ % $n == 0 && $lcv < $num) { // every Nth item, unless we're done
            echo "</div><div>"; //close old one and open new one
        }
    }
    echo "</div>"; //always close the last one.
}

Nur um den Fall zu behandeln, dass bei der Suche überhaupt nichts zurückgegeben wurde.