Переход от дочернего к родительскому для создания разделенных запятыми категорий в PHP

У меня есть данные json в таком файле abc.json.

{
    "meta": {
        "code": 200,
        "requestId": "5afd9043dd57977f0f88d3b1"
    },
    "response": {
        "categories": [
            {
                "id": "1",
                "categories": [
                    {
                        "id": "a",
                        "categories": []
                    },
                    {
                        "id": "b",
                        "categories": [
                                {
                                "id": "c",
                                "categories": []
                                },
                                {
                                    "id": "d",
                                    "categories": [{
                                          "id": "e",
                                          "categories": []
                                          },
                                          {
                                              "id": "f",
                                              "categories": []
                                          }
                                      ]
                                }
                        ]
                    }
                ]
            } ,
            {
                "id": "2",
                "categories": [
                    {
                        "id": "i",
                        "categories": []
                    },
                    {
                        "id": "j",
                        "categories": [
                                {
                                "id": "k",
                                "categories": []
                                },
                                {
                                    "id": "l",
                                    "categories": []
                                }
                        ]
                    }
                ]
            } 
      ]
 }
 }

В коде PHP я хочу перейти от дочернего к родительскому. Например:

if `$child = c`, then 
$categoryString = '1,b,c';

If `$child = i`, then $categoryString = '2,i';

Как я могу этого добиться?

Я пробовал что-то вроде этого: -

function displayRec($a, $parent = "0") {
    if (!empty($a['childs'])) {
        foreach($a['childs'] as $child) {
            displayRec($child, $a['id']);
        }

    }
}

foreach($navArray as $a) {
    displayRec($a);
}

Любая попытка? Петля?

AbraCadaver 17.05.2018 17:07

Почему не рекурсивность?

Fanie Void 17.05.2018 17:09

Используйте json_decode, чтобы декодировать json в массивы, а затем используйте цикл, если вложенность ограничена или рекурсивность, как сказала Фани, если существует неограниченное количество уровней вложенности. php.net/manual/en/function.json-decode.php

Juan Techera 17.05.2018 17:13
Стоит ли изучать 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
3
56
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Я предоставил функцию, которая ищет определенный $childId или «точку входа», чтобы начать движение вверх, пока все родители не будут посещены рекурсивно. При движении вверх он вставляет найденный идентификатор в $result.

Я надеюсь, это поможет вам:

$json = json_decode('{     "meta": {         "code": 200,         "requestId": "5afd9043dd57977f0f88d3b1"     },     "response": {         "categories": [             {                 "id": "1",                 "categories": [                     {                         "id": "a",                         "categories": []                     },                     {                         "id": "b",                         "categories": [                                 {                                 "id": "c",                                 "categories": []                                 },                                 {                                     "id": "d",                                     "categories": [{                                           "id": "e",                                           "categories": []                                           },                                           {                                               "id": "f",                                               "categories": []                                           }                                       ]                                 }                         ]                     }                 ]             } ,             {                 "id": "2",                 "categories": [                     {                         "id": "i",                         "categories": []                     },                     {                         "id": "j",                         "categories": [                                 {                                 "id": "k",                                 "categories": []                                 },                                 {                                     "id": "l",                                     "categories": []                                 }                         ]                     }                 ]             }       ]  }  }');

function print_hierarchy_by_child_id($json,$childId){
  $result = array();
  foreach($json->categories as $category){
    if ($category->id==$childId){
      // the entry-point was found
      $result[] = $category->id;
      return $result;
    }
    else{
      $foundChildCat = print_hierarchy_by_child_id($category, $childId);
      if (count($foundChildCat)){
          // climb up to next parent if an entry-point was found
          $result[] = $category->id;
          $result = array_merge($result, $foundChildCat);
          return $result;
      }
    }
  }
  return $result;
}

$firstExample = print_hierarchy_by_child_id($json->response, "c");
var_dump(implode(",",$firstExample)); // "1,b,c"

$secondExample = print_hierarchy_by_child_id($json->response, "i");
var_dump(implode(",",$secondExample)); // "2,i"
Ответ принят как подходящий

Поиск в глубину. Возвращает пустой массив, если путь не найден, в противном случае - массив идентификаторов в порядке последней глубины:

function path(string $search, array $nodes): array {                             
    foreach ($nodes as $node) {                                                  
        if ($node->id == $search) {                                                                     
            return [ $node->id ];                                                
        } else if (! empty($node->categories)) {                                 
            $path = array_merge([ $node->id ], path($search, $node->categories));
            if (in_array($search, $path)) {                                   
                return $path;                                                 
            }                                                                 
        }                                                                     
    }                                                                         
    return [];                                                                
}   

Применение:

$find = 'f';
$json = json_decode(file_get_contents('data.json'));
$path = path($find, $json->response->categories);
echo implode(',', $path); // outputs 1,b,d,f

Скорее всего не оптимальная реализация. Если ваши данные JSON огромны, рассмотрите возможность перехода от рекурсии к итерации. Если он по-прежнему неэффективен (или просто занимает слишком много оперативной памяти), рассмотрите возможность использования Парсер потоковой передачи JSON.

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