Задать вопрос
81phonk
@81phonk
php is dead?

Как трансформировать массив?

Всем привет! Подскажите, как реализовать логику для изменения массива `messages` в `messages2`.
Нужно сгруппировать элементы по значению `customer_id`, сохранив их порядок. В данном примере сначала нужно сгруппировать элементы с `id = 1` и `2`, затем `3` и `4`, и так далее.

Данные
"messages": [
	{
		"id": 1,
		"customer": "Dr. Kane Hill",
		"customer_id": 1,
		"created_at": "2024-11-19 11:18:57",
		"text": "Hello, how are you?"
	},
	{
		"id": 2,
		"customer": "Dr. Kane Hill",
		"customer_id": 1,
		"created_at": "2024-11-19 11:20:57",
		"text": "I am good, thanks! How about you?"
	},
	{
		"id": 3,
		"customer": "Prof. Samir McClure III",
		"customer_id": 2,
		"created_at": "2024-11-19 11:21:57",
		"text": "Hey, what time is it?"
	},
	{
		"id": 4,
		"customer": "Prof. Samir McClure III",
		"customer_id": 2,
		"created_at": "2024-11-19 11:22:57",
		"text": "It is 3 PM."
	},
	{
		"id": 5,
		"customer": "Shad Leffler",
		"customer_id": 3,
		"created_at": "2024-11-19 11:23:57",
		"text": "Did you finish the project?"
	},
	{
		"id": 6,
		"customer": "Shad Leffler",
		"customer_id": 3,
		"created_at": "2024-11-19 11:24:57",
		"text": "New mesh"
	},
	{
		"id": 7,
		"customer": "Prof. Samir McClure III",
		"customer_id": 2,
		"created_at": "2024-11-19 11:26:57",
		"text": "Not bed?"
	},
	{
		"id": 8,
		"customer": "Prof. Samir McClure III",
		"customer_id": 2,
		"created_at": "2024-11-19 11:27:57",
		"text": "Cool?"
	}
]

"messages2": [
	{
		"customer": "Dr. Kane Hill",
		"messages_id": 1,
		"customer_id": 1,
		"messages": [
			{
				"id": 1,
				"created_at": "2024-11-19 11:18:57",
				"text": "Hello, how are you?",
			},
			{
				"id": 2,
				"created_at": "2024-11-19 11:20:57",
				"text": "I am good, thanks! How about you?",
			}
		]
	},
	{
		"customer": "Prof. Samir McClure III",
		"messages_id": 2,
		"customer_id": 2,
		"messages": [
			{
				"id": 3,
				"created_at": "2024-11-19 11:21:57",
				"text": "Hey, what time is it?",
			},
			{
				"id": 4,
				"created_at": "2024-11-19 11:22:57",
				"text": "It is 3 PM."
			}
		]
	},
	{
		"customer": "Shad Leffler",
		"messages_id": 3,
		"customer_id": 3,
		"messages": [
			{
				"id": 4,
				"created_at": "2024-11-19 11:23:57",
				"text": "Did you finish the project?"
			},
			{
				"id": 5,
				"created_at": "2024-11-19 11:24:57",
				"text": "New mesh"
			}
		]
	},
	{
		"customer": "Prof. Samir McClure III",
		"messages_id": 4,
		"customer_id": 2,
		"messages": [
			{
				"id": 6,
				"created_at": "2024-11-19 11:26:57",
				"text": "Not bed?"
			},
			{
				"id": 7,
				"created_at": "2024-11-19 11:27:57",
				"text": "Cool?"
			},

		]
	},
]


У меня получается какой-то монстр.

Код
public function toArray(Request $request): array
    {
        $messages = $this->whenLoaded('messages')->sortBy('id');

        $messagesGroupedByCustomer = [];
        $messagesIdCounter = 1;
        $currentCustomerId = null;
        $currentCustomerMessages = [];

        foreach ($messages as $message) {
            if ($currentCustomerId !== $message['customer_id']) {
                if ($currentCustomerId !== null) {
                    $messagesGroupedByCustomer[] = [
                        'customer' => $currentCustomerMessages[0]['customer']->full_name,
                        'messages' => array_map(function ($msg) {
                            return [
                                'id' => $msg['id'],
                                'created_at' => $msg['created_at']->toDateTimeString(),
                                'text' => $msg['text'],
                            ];
                        }, $currentCustomerMessages),
                    ];
                    $messagesIdCounter++;
                }

                $currentCustomerId = $message['customer_id'];
                $currentCustomerMessages = [];
            }

            $currentCustomerMessages[] = $message;
        }

        if ($currentCustomerId !== null) {
            $messagesGroupedByCustomer[] = [
                'customer' => $currentCustomerMessages[0]['customer']->full_name,
                'messages' => array_map(function ($msg) {
                    return [
                        'id' => $msg['id'],
                        'created_at' => $msg['created_at']->toDateTimeString(),
                        'text' => $msg['text'],
                    ];
                }, $currentCustomerMessages),
            ];
        }
        $data['date'] = "Сегодня";
        $data['item'] = $messagesGroupedByCustomer;

        return $data;
    }
  • Вопрос задан
  • 156 просмотров
Подписаться 1 Простой 1 комментарий
Помогут разобраться в теме Все курсы
  • Skillfactory
    Профессия Fullstack веб-разработчик на JavaScript и PHP
    20 месяцев
    Далее
  • Хекслет
    PHP-разработчик
    10 месяцев
    Далее
  • Нетология
    Веб-разработчик с нуля: профессия с выбором специализации
    14 месяцев
    Далее
Пригласить эксперта
Ответы на вопрос 1
nokimaro
@nokimaro
Меня невозможно остановить, если я смогу начать.
Делается одним проходом в цикле
Ключем выставляем поле по которому делать группировку и внутрь уже ложим нужные данные
В конце array_values() чтобы переиндексировать результат и сбросить ключи

https://3v4l.org/mZQIN#v8.3.14

<?php
error_reporting(-1);
ini_set('display_errors', 1);

$json_data = <<<JSON
{"messages": [
	{
		"id": 1,
		"customer": "Dr. Kane Hill",
		"customer_id": 1,
		"created_at": "2024-11-19 11:18:57",
		"text": "Hello, how are you?"
	},
	{
		"id": 2,
		"customer": "Dr. Kane Hill",
		"customer_id": 1,
		"created_at": "2024-11-19 11:20:57",
		"text": "I am good, thanks! How about you?"
	},
	{
		"id": 3,
		"customer": "Prof. Samir McClure III",
		"customer_id": 2,
		"created_at": "2024-11-19 11:21:57",
		"text": "Hey, what time is it?"
	},
	{
		"id": 4,
		"customer": "Prof. Samir McClure III",
		"customer_id": 2,
		"created_at": "2024-11-19 11:22:57",
		"text": "It is 3 PM."
	},
	{
		"id": 5,
		"customer": "Shad Leffler",
		"customer_id": 3,
		"created_at": "2024-11-19 11:23:57",
		"text": "Did you finish the project?"
	},
	{
		"id": 6,
		"customer": "Shad Leffler",
		"customer_id": 3,
		"created_at": "2024-11-19 11:24:57",
		"text": "New mesh"
	},
	{
		"id": 7,
		"customer": "Prof. Samir McClure III",
		"customer_id": 2,
		"created_at": "2024-11-19 11:26:57",
		"text": "Not bed?"
	},
	{
		"id": 8,
		"customer": "Prof. Samir McClure III",
		"customer_id": 2,
		"created_at": "2024-11-19 11:27:57",
		"text": "Cool?"
	}
]}
JSON;

$messages = json_decode($json_data, true)['messages'];

$messages2 = [];
$messageCounter = 0;
foreach($messages as $row) {
    
    $key = $row['customer_id'];
    
    if(!isset($messages2[$key])) {
        $messages2[$key] = [
            'customer' => $row['customer'],
            'message_id' => (++$messageCounter),
            'customer_id' => $row['customer_id'],
            'messages' => [],
        ];
    }

    
    $messages2[$key]['messages'][] = [
        'id' => $row['id'],
        'created_at' => $row['created_at'],
        'text' => $row['text'],
    ];
}

$messages2 = array_values($messages2);

echo json_encode($messages2, JSON_PRETTY_PRINT);


upd: подправил ответ, так как по всей видимости message_id в сгруппированном результате должен быть счётчиком
upd2: по совету. Adamos обновил ответ убрав не нужные присваивания при каждом проходе цикла
Ответ написан
Ваш ответ на вопрос

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

Похожие вопросы
FoodSoul Калининград
от 180 000 до 250 000 ₽
IT-Spirit Москва
от 230 000 до 320 000 ₽
от 200 000 до 290 000 ₽