Уменьшите двухмерный массив истории изменений до начальных и конечных значений для каждого идентификатора и удалите строки, в которых нет изменений

Есть массив «движений» элементов, примерно одинаковый, только его может быть в разы больше:

Array
(
    [0] => Array
        (
            [id] => 90415
            [oldDate] => 2024-08-27
            [newDate] => 2024-08-28
        )

    [1] => Array
        (
            [id] => 90415
            [oldDate] => 2024-08-28
            [newDate] => 2024-08-27
        )

    [2] => Array
        (
            [id] => 90409
            [oldDate] => 2024-08-21
            [newDate] => 2024-08-22
        )

    [3] => Array
        (
            [id] => 90409
            [oldDate] => 2024-08-22
            [newDate] => 2024-08-23
        )
)

Я пытаюсь сделать так, чтобы все промежуточные перемещения элемента были удалены, остались только начальные и конечные, а также были удалены элементы массива, где элемент возвращается в исходное положение (0 и 1 элементы массив). В итоге обработанный массив должен выглядеть так:

Array
(
    [0] => Array
        (
            [id] => 90409
            [oldDate] => 2024-08-21
            [newDate] => 2024-08-23
        )
)

как это сделать, чтобы массив из большого количества элементов не задерживал выполнение скрипта на долгое время

определить «большое количество элементов». И что потом нужно делать с обработанным массивом? Нужно ли возвращать его пользователю, инициирующему вызов? Кроме того, что вы пробовали?

Gordon 15.08.2024 15:11

Обработанный массив затем будет отправлен в отдельный метод, который продолжит с ним работать. Пытался это сделать, но не могу разобраться: 1) Как понять, что элемент newDate последний, и удалить все остальные элементы, оставив 2 значения, и нужно перебрать все элементы элемента массив, вам нужно составить регулярное выражение? 2) Как удалить только элементы с противоположными oldDate и newDate, оставив остальные с такими же ID

user23964512 15.08.2024 15:21

что вы в конечном итоге делаете с обработанным массивом? Я спрашиваю, потому что вы могли бы подумать о передаче массива в очередь сообщений для его асинхронной обработки, если вам не нужно возвращать его куда-то в текущем запросе. Таким образом, выполнение скрипта не будет задерживаться.

Gordon 15.08.2024 15:24

И еще: насколько велико большое? Мы говорим о 1000 или миллионах? миллиарды?

Gordon 15.08.2024 15:25

Отсортирован ли этот массив таким образом, чтобы мы могли быть уверены, что первое появление нового идентификатора сохранит его исходную позицию? Или может быть ['id' => 90409, 'oldDate' => '2024-08-20', 'newDate' => '2024-08-21'] после начального ['id' => 90409, 'oldDate' => '2024-08-22', 'newDate' => '2024-08-23'],?

Gordon 15.08.2024 16:03
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
1
5
56
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Вот решение, использующее промежуточный ассоциативный массив $data, который обеспечивает эффективный поиск:

$moves = [
    ['id' => 90415, 'oldDate' => '2024-08-27', 'newDate' => '2024-08-28'],
    ['id' => 90415, 'oldDate' => '2024-08-28', 'newDate' => '2024-08-27'],
    ['id' => 90409, 'oldDate' => '2024-08-21', 'newDate' => '2024-08-22'],
    ['id' => 90409, 'oldDate' => '2024-08-22', 'newDate' => '2024-08-23'],
    ];

$data = [];
foreach($moves as $move)
{
    $id = $move['id'];
    if (isset($data[$id]))
    {
        // Id already present, update its newDate
        $data[$id]['newDate'] = $move['newDate'];
    }
    else
    {
        // New id, store it
        $data[$id] = $move;
    }
}

// Keep ids with different oldDate and newDate
$result = array_filter($data, fn($move) => $move['oldDate'] != $move['newDate']);

// Remove array keys
$result = array_values($result);

var_export($result);

Выход:

array (
  0 => 
  array (
    'id' => 90409,
    'oldDate' => '2024-08-21',
    'newDate' => '2024-08-23',
  ),
)

Просто для сравнения, вот функциональный эквивалент (безупречного) решения Оливье. Демо

var_export(
    array_values(
        array_filter(
            array_reduce(
                $movements,
                function($carry, $move) {
                    $carry[$move['id']] ??= $move;
                    $carry[$move['id']]['newDate'] = $move['newDate'];
                    return $carry;
                }
            ),
            fn($move) => $move['oldDate'] != $move['newDate']
        )
    )
);

Это также можно записать так: Демо

$grouped = [];
foreach ($movements as $move) {
    $grouped[$move['id']] ??= $move;                     // store if a new id
    $grouped[$move['id']]['newDate'] = $move['newDate']; // overwrite stored newDate
}

var_export(
    array_values(
        array_filter(
            $grouped,
            fn($move) => $move['oldDate'] != $move['newDate']
        )
    )
);

Другие вопросы по теме