Объединить подмассивы многомерного массива на основе вложенного значения

У меня есть такой многомерный массив, мне нужно объединить подмассивы с одинаковым значением messageID.


$myarray = Array (

    [0] => Array
        (
            [messageId] => 5ACE9D8841
            [sender] => [email protected]
        )

    [1] => Array
        (
            [messageId] => 7EE67D8170
            [sender] => [email protected]
        )

    [2] => Array
        (
            [messageId] => 8095FD8836
            [sender] => [email protected]
        )

    [3] => Array
        (
            [messageId] => 7EE67D8170
            [dest] => [email protected]
            [status] => sent
            [date] => 2021-02-01 11:06:55
        )
);

Ожидаемый результат, [1] и [3] объединяются в [1], поскольку они имеют один и тот же [messageId]:


Array
(
    [0] => Array
        (
            [messageId] => 5ACE9D8841
            [sender] => [email protected]
        )

    [1] => Array
        (
            [messageId] => 7EE67D8170
            [dest] => [email protected]
            [status] => sent
            [date] => 2021-02-01 11:06:55
            [sender] => [email protected]
        )

    [2] => Array
        (
            [messageId] => 8095FD8836
            [sender] => [email protected]
        )
)

Я не возражаю против ключевого индекса или порядка.

РЕДАКТИРОВАТЬ: я пробовал array_merge, array_merge_recursive и многие другие. Наилучший результат был получен с


        foreach ($myarray as $sub_arr) {

            $result_arr = array_merge($result_arr, $sub_arr);

            $result_arr = array_unique($result_arr);


        } 

Он работает, но возвращает только последнюю итерацию:

Array
        (
            [messageId] => 7EE67D8170
            [dest] => [email protected]
            [status] => sent
            [date] => 2021-02-01 11:06:55
            [sender] => [email protected]
        )

С Уважением


person dubwise    schedule 05.02.2021    source источник
comment
что ты уже испробовал?   -  person Felippe Duarte    schedule 05.02.2021
comment
Добро пожаловать в Stack Overflow. Хотя мы рады помочь, когда вы застряли, вы все равно должны приложить усилия для достижения решения. Это простая задача повторения одного массива для создания нового. Если вы уже пробовали что-то, отредактируйте свой вопрос, чтобы показать свою лучшую попытку и объяснить, где и как она не делает то, что вам нужно.   -  person El_Vanja    schedule 05.02.2021
comment
@El_Vanja Ty, я отредактировал свой пост.   -  person dubwise    schedule 05.02.2021
comment
@FelippeDuarte Я отредактировал свой пост, я пробовал сам весь день.   -  person dubwise    schedule 05.02.2021
comment
Суть вашей проблемы в том, что вы пытаетесь безоговорочно объединиться на каждой итерации. Вы должны объединяться только тогда, когда выполняется определенное условие (идентификаторы совпадают). В противном случае все, что вам нужно сделать, это добавить элемент как есть в результирующий массив. Вы можете использовать идентификатор сообщения в качестве ключа в результирующем массиве, чтобы было легко определить, существует ли этот идентификатор сообщения в результате и должен быть объединен.   -  person El_Vanja    schedule 05.02.2021
comment
@El_Vanja спасибо за вашу помощь, я думал, что есть простой способ, о котором я не знаю, с чем-то вроде array_merge. Я постараюсь научиться использовать условия между итерациями.   -  person dubwise    schedule 05.02.2021
comment
@dubwise можете ли вы указать, отредактировав, какой ответ вы ожидаете для объединенного массива   -  person    schedule 05.02.2021
comment
@King619 Извините, я думаю, что не понимаю, что вы хотите, чтобы я сделал, поскольку я уже дал ожидаемый результат на свой вопрос.   -  person dubwise    schedule 06.02.2021


Ответы (1)


Попробуйте использовать функцию array_reduce с функцией обратного вызова:

$result = array_values(array_reduce($myarray, function($rows, $item){
    if (array_key_exists('messageId', $item) && is_scalar($item['messageId'])) {
        $rows = array_replace_recursive($rows ?? [], [$item['messageId'] => $item]);
    }
    return $rows;
}));

print_r($result);

скрипка

person user14717238    schedule 06.02.2021
comment
привет, большое спасибо за вашу помощь. В примере со скрипкой я думаю, что это почти хорошо, но отправитель ( 'sender' => '[email protected]') отсутствует для messageId 7EE67D8170 - person dubwise; 06.02.2021
comment
Я обновил ответ и скрипку. Должна быть функция array_replace_recursive вместо array_merge. - person user14717238; 06.02.2021
comment
Отлично, большое спасибо за вашу помощь! - person dubwise; 06.02.2021