按列对菜单项进行排序

I am trying to group my menu by alphabets and splitting them in columns. So I have an associative array where my items are already sorted by alphabets.

foreach ($category['children'] as $children) {
  $firstChar = $children['name'][0];


  // if character is a number set it as #
  if (is_numeric($firstChar)) {
    $firstChar = "#";
  }

  if ($firstChar !== $previousChar) {
    echo '<li class="submenu_tag">'.strtoupper($firstChar).'</li>';
    $previousChar = $firstChar;
  }

  echo '<li><a href="'.$children['href'].'">'.$children['name'].'</a></li>';
  $count++;
  if ($count == 11) {
     echo '</ul></div>';
     echo '<div><ul>';
     $count = 0;
  }
}
echo '</ul></div>';

What I have now will output this.

<div>   <div>      <div>
A       Cow        Fawn
Apple   Crab       Fish
Ape                Fox
Ant     D          
        Dog        G
B                  Gazette
Boy     E          Goose
Ball    Elephant   Gorilla
Bad     Egg        
        Elk        H   
C                  Hedgehog
Camel   F          Hen
Cat     Falcon     
</div>  </div>     </div>

The desired result would be if the following few items that belongs in a group is going to exceed 11 rows (excluding the empty spaces in between) then it will move it to a new div. Something like this:

<div>   <div>      <div>
A       C          F
Apple   Cat        Falcon
Ape     Cow        Fawn
Ant     Crab       Fish
                   Fox
B       D          
Boy     Dog        G     
Ball               Gazette
Bad     E          Goose       
        Elephant   Gorilla     
        Egg
        Elk        .....
</div>  </div>     </div>

Try this code

function formatData($datas)
{
    $outputs = [];
    $previousChar = "";
    foreach ($datas as $data) {
        $firstChar = $data['name'][0];
        if (is_numeric($firstChar)) {
            $firstChar = "#";
        }

        if ($firstChar !== $previousChar) {
            $previousChar = $firstChar;
            $outputs[$firstChar]   = [];
            //keep Key
            $outputs[$firstChar][] = [
                'name' => $firstChar,
            ];
        }

        $outputs[$firstChar][] = $data;
    }
    return $outputs;
}

function crateItemHtml($item)
{
    $output = '<li>';
    if (isset($item['href'])) {
        $output .= '<a href="'.$item['href'].'">';
    }
    if (isset($item['name'])) {
        $output .= $item['name'];
    }
    if (isset($item['href'])) {
        $output .= '</a>';
    }
    $output .= '</li>';
    return $output;
}

$datas = formatData($categories);

$maxRow = 11;
$count  = 0;
if (!empty($datas)) {

    echo '<div style="width:150px; float:left;"><ol>';
    foreach ($datas as $data) {
        $totalGroup = count($data);

        if (($count+$totalGroup) >= $maxRow) {
            //create space
            while ($count < $maxRow) {
                $count++;
                //add space
                echo crateItemHtml([]);
            }
            $count = 0;
            echo '</ol></div>';
            echo '<div style="width:150px; float:left;"><ol>';
        }

        //can add in row
        foreach ($data as $category) {
            $count++;
            echo crateItemHtml($category);
        }
        if ($count < $maxRow) {
            $count++;
            //add space
            echo crateItemHtml([]);
        } else {
            $count = 0;
            echo '</ol></div>';
            echo '<div style="width:150px; float:left;"><ol>';
        }

    }

    echo '</ol></div>';
}

you can change max row in this line

$maxRow = 11;