За последние 24 часа нас посетили 31790 программистов и 1364 робота. Сейчас ищут 842 программиста ...

Рекурсивное получение цепочек ключей в многомерном массиве

Тема в разделе "PHP для новичков", создана пользователем ELEMENTAL Limited, 14 окт 2016.

  1. ELEMENTAL Limited

    ELEMENTAL Limited Новичок

    С нами с:
    14 окт 2016
    Сообщения:
    19
    Симпатии:
    6
    Доброго времени суток. Путем несложных манипуляций был получен массив такого типа:
    Код (Text):
    1. Array
    2. (
    3.     [0] => Array
    4.         (
    5.             [0] => Array
    6.                 (
    7.                     [a] => 2
    8.                 )
    9.             [1] => Array
    10.                 (
    11.                     [b] => 1
    12.                 )
    13.         )
    14.     [1] => Array
    15.         (
    16.             [0] => Array
    17.                 (
    18.                     [0] => Array
    19.                         (
    20.                             [c] => 1
    21.                         )
    22.  
    23.                     [1] => Array
    24.                         (
    25.                             [d] => 1
    26.                         )
    27.                 )
    28.             [1] => Array
    29.                 (
    30.                     [e] => 1
    31.                 )
    32.         )
    33. )
    Необходимо получить цепочку ключей для каждого элемента, как вариант:
    Код (Text):
    1. Array
    2. (
    3.     [a] => 00
    4.     [b] => 01
    5.     [c] => 100
    6.     [d] => 101
    7.     [e] => 11
    8. )
    Лично я вижу решение, как рекурсивный обход массива и [ если массив ] добавляем в строку индекс, как только упираемся в элемент - добавляем разделитель. Но проблема в том, что после добавления разделителя необходимо удалить родительский массив элемента и начать рекурсию заново. И так до тех пор пока не получим пустой массив. В конце просто заэксплодим строку по разделителю.

    Не получается удалить родительский массив для найденного элемента и начать рекурсию заново. Думаю, если решить эту проблему, то сделаю сам
     
  2. denis01

    denis01 Суперстар
    Команда форума Модератор

    С нами с:
    9 дек 2014
    Сообщения:
    12.227
    Симпатии:
    1.714
    Адрес:
    Молдова, г.Кишинёв
    Может просто при обходе массива рекурсивно, то результаты писать в новый массив не трогая источник?
     
    ELEMENTAL Limited нравится это.
  3. ELEMENTAL Limited

    ELEMENTAL Limited Новичок

    С нами с:
    14 окт 2016
    Сообщения:
    19
    Симпатии:
    6
    Спасибо, но справился немного по другому
    Получил массив индексов всех элементов на последнем уровне вложенности. Потом рекурсивно искал их в многомерном массиве, с каждым вложенным массивом записывал индекс, если натыкался на элемент - эксепшеном выкидывал себя из рекурсии, если найден другой элемент - удаляем один индекс с конца накопленных, так как мы на другой уровень вложенности в рекурсии переходим. А потом отлавливал исключения для каждого элемента
    Возможно, костыльно, но тем не менее, работает

    Я просто не сразу понял, что после foreach в рекурсии можно внести значимый код
     
    #3 ELEMENTAL Limited, 14 окт 2016
    Последнее редактирование: 14 окт 2016
    denis01 нравится это.
  4. serega_dgl

    serega_dgl Новичок

    С нами с:
    11 фев 2018
    Сообщения:
    3
    Симпатии:
    0
    Одним из способов является цикл for..each с некоторыми операциями изменения массива:

    //$input is your original input array

    // final output array
    $output = array();

    // Loop over the array
    foreach ($input as $key => $value) {

    $output[$key]['group_id'] = $value['group_id'];

    // Set recipients key at the same level as group_id
    // Access the value at [0]['recipients']
    $output[$key]['recipients'] = $value[0]['recipients'];
    }
    http://q-answer.ru/questions/kak-udalit-roditel-skiy-massiv-v-php-30394.html
     
  5. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    11.128
    Симпатии:
    1.248
    Адрес:
    там-сям
    "Цепочка ключей" это похоже на материализованный путь.

    У тебя только 0 и 1 могут быть ключами? То есть двоичное дерево и никак иначе? Потому что при более чем одном символе в ключе уже напрашивается вставка разделителя между именами, чтобы смысл не исказился.
     
  6. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    11.128
    Симпатии:
    1.248
    Адрес:
    там-сям
    сделал на анонимных функциях. допущения и тайные знания:
    - функция array_walk_recursive вызывает лямбду только для конечных элементов (не-массивов)
    - считаем, что "конечные" ключи уникальны
    - считаем, что "не конечные" ключи бывают только из одного символа, поэтому не страшно, что не будет разделителя между ними
    - чтобы рекурсивно обратиться из лямбды к ней же самой, надо передать её по ссылке

    PHP:
    1. <?php
    2.  
    3. $source = [
    4.   '0' => [
    5.     '0' => [
    6.       'a' => 2,
    7.     ],
    8.     '1' => [
    9.       'b' => 1,
    10.     ],
    11.   ],
    12.   '1' => [
    13.     '0' => [
    14.       '0' => [
    15.         'c' => 1,
    16.       ],
    17.       '1' => [
    18.         'd' => 1,
    19.       ],
    20.     ],
    21.     '1' => [
    22.       'e' => 1,
    23.     ],
    24.   ]
    25. ];
    26.  
    27. // find end points
    28. $keys = [];
    29. array_walk_recursive($source, function ($dummy, $key) use (&$keys) {
    30.     $keys[$key] = null;
    31. });
    32. // recusrsion to find paths end end points
    33. $func = function ($a, $path) use(&$func, &$keys) {
    34.     foreach ($a as $k => $v) {
    35.         if (!is_array($v)) {
    36.             $keys[$k] = $path;
    37.         } else {
    38.             $func($v, $path . $k);
    39.         }
    40.     }
    41. };
    42. $func($source, '');
    43. // debug output
    44. var_export($keys);
    запускаем:
    Код (Text):
    1. $ php test.php
    2. array (
    3.   'a' => '00',
    4.   'b' => '01',
    5.   'c' => '100',
    6.   'd' => '101',
    7.   'e' => '11',
    8. )
     
  7. Valick

    Valick Активный пользователь

    С нами с:
    12 авг 2018
    Сообщения:
    1.911
    Симпатии:
    328
    внимательно смотрим дату поста ТС
     
  8. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    11.128
    Симпатии:
    1.248
    Адрес:
    там-сям
    да плевать, Валик. можно подумать свежие посты имеют больше смысла )))
    --- Добавлено ---
    лишь бы ты учился хорошо!
     
  9. Valick

    Valick Активный пользователь

    С нами с:
    12 авг 2018
    Сообщения:
    1.911
    Симпатии:
    328
    само собой.. завтра по информатике получу четвёрку и поставлю её в холодильник