Вот так вроде работает:
$html = array_reduce(array_keys($arData), function($data, $i) use ($arData) {
$item = $arData[$i];
$is_last_item = $i == count($arData) - 1;
if ($i == 0) {
$data['result_html'] = '<div class="items-container">';
if ($item['group']) {
$data['group_html'] = '<div class="group" data-group="' . $item['group'] . '">'
. '<div class="item">' . $item['title'] . '</div>';
} else {
$data['result_html'] .= '<div class="item">' . $item['title'] . '</div>';
}
} else {
if ($item['group']) {
$previous_item = $arData[$i - 1];
if ($previous_item['group']) {
if ($previous_item['group'] == $item['group']) {
$data['group_html'] .= '<div class="item">' . $item['title'] . '</div>';
} else {
$data['result_html'] .= $data['group_html'] . '</div>';
$data['group_html'] = '<div class="group" data-group="' . $item['group'] . '">'
. '<div class="item">' . $item['title'] . '</div>';
}
} else {
$data['group_html'] = '<div class="group" data-group="' . $item['group'] . '">'
. '<div class="item">' . $item['title'] . '</div>';
}
if ($is_last_item) {
$data['result_html'] .= $data['group_html'] . '</div>' ;
}
} else {
if (strlen($data['group_html'])) {
$data['result_html'] .= $data['group_html'] . '</div>';
$data['group_html'] = '';
}
$data['result_html'] .= '<div class="item">' . $item['title'] . '</div>';
}
}
if ($is_last_item) {
$data['result_html'] .= '</div>' ;
return $data['result_html'];
} else {
return $data;
}
}, [
'result_html' => '',
'group_html' => '',
]);
Только у вас в ожидаемом результате, кажется, ошибка: должно быть
<div class="group" data-group="3">
вместо
<div class="group" data-group="4">