user2203484
user2203484

Reputation: 77

Flattening array

I have a function which changes an array into the html list (ol/ul). The depth of the array is passed as an argument.

I wanted to do this in just a single function.

for($i = 0; $i < $depth; $i++) {
   foreach($list_array as $li) {
      if(! is_array($li))
      {
         $str .= '<li>' . $li . '</li>';
      }
   }
}

This code gives me the first dimension of the array. I'd like to flatten this array every time the $i increments.

Do you have any suggestions that could be helpful?

And yes, I'm aware of array_walk_recursive(), object iterators etc...I'd like to know if there's a simple way to do this task without using any ot those. I can't come up with anything.

And no, this is not any university project where I'm not allowed to use iterators etc.

EDIT:

print_list(array(
   'some first element',
   'some second element',
   array(
      'nested element',
      'another nested element',
      array(
         'something else'
      )
   )
));

should output something like:

<ul>
   <li>some first element</li>
   <li>some second element</li>
   <ul>
      <li>nested element</li>
      <li>another nested element</li> // etc

Upvotes: 0

Views: 102

Answers (2)

Barmar
Barmar

Reputation: 780688

function print_list($array) {
  echo '<ul>';
  // First print all top-level elements
  foreach ($array as $val) {
    if (!is_array($val)) {
      echo '<li>'.$val.'</li>';
    }
  }
  // Then recurse into all the sub-arrays
  foreach ($array as $val) {
    if (is_array($val)) {
      print_list($val);
    }
  }
  echo '</ul>';
}

Upvotes: 1

Mark Elliot
Mark Elliot

Reputation: 77024

This is probably easiest to accomplish using recursion:

function print_list($array){
    echo '<ul>';
    // examine every value in the array
    // (including values that may also be arrays)
    for($array as $val){
        if(is_array($val){
            // when we discover the value is, in fact, an array
            // print it as if it were the top-level array using
            // this function
            print_list($val);
        }else{
            // if this is a regular value, print it as a list item
            echo '<li>'.$val.'</li>';
        }
    }
    echo '</ul>';
}

If you want to do indentation, you could define a depth tracking parameter and a co-routine (print_list_internal($array, $depth)) or just add a default parameter (print_list($array,$depth=0)) and then print a number of spaces in front of anything depending on $depth.

Upvotes: 1

Related Questions