@burtellbee

Выборка и сравнение данных массива PHP?

Есть массив PHP, состоящий из объектов, родитель и его потомки.
Т.е. У каждого объекта есть поле со значением ID, у потомка также есть поле с ID родителя. У потомка дополнительно есть поле с датой начала и поле с датой конца события. У Родителя таких полей нет.
Как осуществить выборку всех потомков родителя, затем сравнить у выбранных потомков одного родителя все значения полей даты начала и даты конца, выбрать конечные значения и присвоить их родителю (добавить в новый массив со значениями крайних полей).
Теперь про задачу обычным языком - есть объект Этап, у него может быть неограниченное количество работ, у каждой работы есть дата начала и дата окончания работы. Необходимо Этапу присваивать значения начала самой "ранней работы" и значения окончания самой "поздней" работы.
  • Вопрос задан
  • 601 просмотр
Решения вопроса 2
Maksclub
@Maksclub Куратор тега PHP
maksfedorov.ru
Сделал на примере массивов, можно на объекты переделать :)

В одну итерацию (если, конечно, я правильно понял задачу): родитель и дети лежат плоско и для одного уровня вложенности. Если есть вложенности, то код будет немного по-другому выглядеть.

<?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...
Ответ написан
nokimaro
@nokimaro
Меня невозможно остановить, если я смогу начать.
Делается ровно так как описано в вопросе.
Начинаете обход массива в цикле через foreach и пишете всю логику
Делать предварительно выборку всех потомков родителя нет смысла. Всё можно сделать в один проход по всем элементам используя результирующий массив $result как хранилище состояния

$result = []; 
//перебираем в цикле все элементы из исходного массива
foreach($input as $row)
{
    //есть поле - значит это дочерний элемент
    if(isset($row->dates))
    { 
       foreach($row->dates as $date_val)
       {
            //тут нужная логика по нахождению мин макс даты у потомков
       }

       //нужные значения записываем по id-родителя в $result
       //$result[$row->parent_id]['min_date'] = ...
    }
    else
    {
        //вносим родителя в $result
        $result[$row->id] = $row;
    }
}
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы
YCLIENTS Москва
от 200 000 до 350 000 ₽
Ведисофт Екатеринбург
от 25 000 ₽
ИТЦ Аусферр Магнитогорск
от 100 000 до 160 000 ₽