Как разделить многомерный массив на несколько одноуровневых массивов по заданным ключам?

Как можно разбить массив на подмассивы по значениям ключа 'key', обеспечив уникальность значений ключа 'name' и объединение повторяющихся значений ключа 'id' в значение ключа 'ids', разделённые запятой? Из исходного массива должны получиться два подмассива, в то время как список возможных значений ключей задан как $keys = ['region', 'city'].
  • 8 ноября 2024 г. 16:03
Ответы на вопрос 2
Чтобы разделить многомерный массив на одноуровневые массивы по заданным ключам и обеспечить уникальность значений по ключу 'name' с объединением значений по ключу 'id', можно использовать PHP. Вот пример кода, который иллюстрирует, как это можно сделать:

```php
function splitArray($data, $keys) {
    $result = [];

    foreach ($data as $item) {
        foreach ($keys as $key) {
            // Проверяем, установлен ли текущий ключ в элементе
            if (isset($item[$key])) {
                $keyValue = $item[$key];

                // Если еще нет подмассива для этого ключа, создаем его
                if (!isset($result[$keyValue])) {
                    $result[$keyValue] = [
                        'name' => $item['name'],
                        'ids' => [],
                    ];
                }
                
                // Убедимся, что 'name' уникален
                if (!in_array($result[$keyValue]['name'], array_column($result, 'name'))) {
                    $result[$keyValue]['name'] = $item['name'];
                }

                // Добавляем id только если его еще нет в массиве
                if (!in_array($item['id'], $result[$keyValue]['ids'])) {
                    $result[$keyValue]['ids'][] = $item['id'];
                }
            }
        }
    }

    // Форматируем ids в виде строки, разделенной запятыми
    foreach ($result as &$resItem) {
        $resItem['ids'] = implode(',', $resItem['ids']);
    }

    return $result;
}

// Пример использования функции:
$data = [
    ['region' => 'North', 'city' => 'A', 'name' => 'Location1', 'id' => 1],
    ['region' => 'North', 'city' => 'A', 'name' => 'Location1', 'id' => 2],
    ['region' => 'North', 'city' => 'B', 'name' => 'Location2', 'id' => 3],
    ['region' => 'South', 'city' => 'A', 'name' => 'Location3', 'id' => 4],
    ['region' => 'South', 'city' => 'B', 'name' => 'Location4', 'id' => 5],
];

$keys = ['region', 'city'];
$result = splitArray($data, $keys);

print_r($result);
```

### Пояснение кода:
1. **Инициализация результата**: Создаем пустой массив `$result` для хранения подмассивов.
2. **Цикл по элементам данных**: Проходим через каждый элемент входного массива `$data`.
3. **Второй цикл по ключам**: Для каждого элемента мы проверяем, установлен ли ключ (например, 'region' или 'city').
4. **Добавление в результат**: Если уже есть подмассив для текущего значения ключа, добавляем данные о 'name' и 'ids'. Убедимся, что 'name' уникален, и добавляем 'id' в подмассива, избегая дублирования.
5. **Форматирование 'ids'**: Преобразуем массив 'ids' в строку, разделённую запятыми.
6. **Возвращение результата**: Возвращаем полученный массив.

Этот код должен позволить вам разбить многомерный массив на подмассивы по значениям ключа 'region' и 'city' с учетом ваших требований.
$grouped = [];

foreach ($arr as [ 'id' => $id, 'name' => $name, 'key' => $key ]) {
  $grouped[$key][$name] ??= [ 'name' => $name, 'ids' => [] ];
  $grouped[$key][$name]['ids'][] = $id;
}

foreach ($keys as $k) {
  $$k = array_map(fn($n) => [
    'name' => $n['name'],
    'ids' => implode(', ', $n['ids'])
  ], array_values($grouped[$k] ?? []));
}
Похожие вопросы