0

I have an indexed array of associative arrays like so:

array 
  0 => 
    array 
      'topic' => 'Topic 1'
      'question' => 'Topic 1, Question 1'
      'answer' => no'
  1 => 
    array 
      'topic' => 'Topic 2'
      'question' => 'Topic 2, Question 1'
      'answer' => 'yes'
  2 => 
    array 
      'topic' => 'Topic 2'
      'question' => 'Topic 2, Question 2'
      'answer' => 'yes'
  3 => 
    array 
      'topic' => 'Topic 3'
      'question' => 'Topic 3, Question 1'
      'answer' => 'yes'

and I would like to output markup that 1) Creates a header for each unique section based on the topic key; and 2) Wraps each discrete section in a <section> element like so:

<section>
    <header>Topic 1</header>
    <p>Topic 1, Question 1</p>
</section>
<section>
    <header>Topic 2</header>
    <p>Topic 2, Question 1</p>
    <p>Topic 2, Question 2</p>
</section>
<section>
    <header>Topic 3</header>
    <p>Topic 3, Question 1</p>
</section>

I've been able to set up a foreach loop that correctly generates the headers for each topic, but I'm having trouble adding the opening/closing <section> elements as needed. I'm currently using array_key_first and array_key_last to add <section> elements around the entire set, but how can I adjust this loop to add open/close section elements for each topic group?

$topic = null;
foreach ( $array as $key => $item ) {
    if ( $key === array_key_first($array) ) {
        $html .= '<section>';
    }
    if ( $item['topic'] != $topic ) {
        $topic = $item['topic'];
        $html .= '<header>' . $topic . '</header>';
    }
    
    $html .= '<p>Question: ' . $item['question'] . '</p>';
    $html .= '<p>Answer: ' . $item['answer'] . '</p>';
    
    if ( $key === array_key_last($array) ) {
        $html .= '</section>';
    }
}
nickpish
  • 839
  • 4
  • 24
  • 43
  • 1
    restructure the array as you intend to loop it out, then you don't need to add any logic/messy concatenation to your view, just have 2 foreach's – Lawrence Cherone May 06 '22 at 14:13
  • Thanks @LawrenceCherone - can you be more specific as to how I could restructure the array in that way? – nickpish May 06 '22 at 14:17
  • 1
    What you want, is a classic _control break_ implementation. Compare the current value of your break criterion with that of the previous iteration, and depending on whether they are the same or differ, you create the necessary output accordingly. – CBroe May 06 '22 at 14:22
  • 1
    for example like this: https://3v4l.org/0RL6n Its not a bad practice to build values in the structure you need which are easy to read and debug vs juggling from a flat structure to a nested one on display – Lawrence Cherone May 06 '22 at 14:35
  • @LawrenceCherone - this is great, thank you; if you can, please post that code as an answer and I'll mark it as accepted! – nickpish May 06 '22 at 14:44

0 Answers0