Sort the array first.
Assuming you start with ...
$options = [
[ 'type' => 'Visual disability', 'name' => 'Audio-described cut-scenes' ],
[ 'type' => 'Visual disability', 'name' => 'Highlighted path to follow' ],
[ 'type' => 'Physical disability', 'name' => 'Sensitivity settings for all the controls' ],
[ 'type' => 'Visual disability', 'name' => 'Screen readers on menus' ],
[ 'type' => 'Visual disability', 'name' => 'Slow down the game speed' ],
];
then ...
#
# Sort the array by type (descending)
#
usort($options, function($a, $b) { return $b['type'] <=> $a['type']; });
#
# process the array
#
$prev_type = ''; // store previous type
echo "<ul>\n";
foreach ($options as $opt) {
if ($opt['type'] != $prev_type) { // is this a new type?
if ($prev_type != '') { // was there a previous one?
echo "</ul>\n</li>\n"; // if so, close it
}
echo "<li>{$opt['type']}\n<ul>\n";
$prev_type = $opt['type']; // store as previous value
}
echo "<li>{$opt['name']}</li>\n";
}
// close last group
echo "</ul>\n</li>\n";
// close whole list
echo "</ul>\n";
giving ...
<ul>
<li>Visual disability
<ul>
<li>Audio-described cut-scenes</li>
<li>Highlighted path to follow</li>
<li>Screen readers on menus</li>
<li>Slow down the game speed</li>
</ul>
</li>
<li>Physical disability
<ul>
<li>Sensitivity settings for all the controls</li>
</ul>
</li>
</ul>
An alternative approach is to reorganise the array using subarrays for each type...
$options = [
'Visual disability' => [ 'Audio-described cut-scenes',
'Highlighted path to follow',
'Screen readers on menus',
'Slow down the game speed'
],
'Physical disability' => [ 'Sensitivity settings for all the controls'
]
];
then use two nested foreach() loops.