Сделал на примере массивов, можно на объекты переделать :)
В одну итерацию (если, конечно, я правильно понял задачу): родитель и дети лежат плоско и для одного уровня вложенности. Если есть вложенности, то код будет немного по-другому выглядеть.
<?php
$data = [
[
'id' => 4,
],
[
'id' => 1,
'start' => 1,
'end' => 50,
'parent_id' => 4,
],
[
'id' => 1,
'start' => 10,
'end' => 50,
'parent_id' => 4,
],
[
'id' => 1,
'start' => 5,
'end' => 100,
'parent_id' => 4,
],
];
function aggregateExtremumBorders(array $elements) {
return array_reduce($elements, function($res, $element) {
if (!isset($element['parent_id'])) {
return $res;
}
$parentId = $element['parent_id'];
$parent = $res[$parentId] ?? ['id' => $parentId, 'min' => null, 'max' => null];
$parent['min'] = min($parent['min'], $element['start']) ?: $element['start'];
$parent['max'] = max($parent['max'], $element['end']) ?: $element['end'];
$res[$parentId] = $parent;
return $res;
}, []);
}
var_dump(aggregateExtremumBorders($data));
sandbox.onlinephpfunctions.com/code/7b43e0e4d8cf9d...