2016-03-02 2 views
0

У меня есть рекурсивная структура $data, которую мне нужно изменить. Каждый узел, считающийся $item, должен получить свойство со значением $value. Вещи, которые я пробовал (и как они потерпели неудачу):Как сделать массив_walk_recursive посещением каждого узла?

  • array_walk_recursive: Посещает только узлы листа.
  • Stack/queue: Мне не удалось изменить исходную структуру, но изменили только копии в стеке/очереди.
  • Петли: Без подхода к стеку/очереди мне нужно знать уровень гнездования и писать очень много вложенных циклов.
  • array_map: Мне не удалось написать правильный рекурсивный обратный вызов, учитывая, что значение $value не является статическим, а результатом предыдущего кода. Поэтому он должен каким-то образом «входить» в обратный вызов. Поскольку use доступен только для анонимных функций, мне не удалось написать рекурсивный.
  • Петля и рекурсивная функция: This answer к аналогичному вопросу не удалось по той же причине, что и подход array_map.

Моя ситуация в коде выглядит как на примере:

<?php 

$value = 'example'; 

$data = array(
    'foo' => 'bar' 
    'items' => array(
     array(
      'foo' => 'bar', 
      'items' => array(
       array('foo' => 'bar') 
      ) 
     ) 
    ) 
); 

// do this recursively to every member of an 'items' property: 
$item['baz'] = $value; 

Вы можете думать о другом подходе или помочь мне выпрямить одну из тех, что я потерпел неудачу в до сих пор?

Update

код, который я попробовал, что не получилось:

// Parse error: syntax error, unexpected 'use' (T_USE), expecting '{' 

function do (&$item) use ($value) { 

    $item['baz'] = $value; 

    foreach ($item['items'] as $next) { 

     do($next); 
    } 
} 

// Undefined variable: value 

function do (&$item) { 

    $item['baz'] = $value; 

    foreach ($item['items'] as $next) { 

     do($next); 
    } 
} 

foreach ($data['items'] as $item) { 

    do($item); 
} 

работ сейчас (я бы предпочел не иметь, чтобы передать параметр $value, хотя):

function do (&$item, $value) { 

    $item['baz'] = $value; 

    foreach ($item['items'] as &$next) { 

     do($next, $value); 
    } 
} 

foreach ($data['items'] as &$item) { 

    do($item, $value); 
} 
+0

Вы пробовали писать * рекурсивную функцию * ...? – deceze

+0

'Мне нужно знать уровень гнездования и писать ужасно много вложенных циклов.' Ough? Вы, кажется, пропустили предмет, называемый рекурсией: https://en.wikipedia.org/wiki/Recursion_(computer_science) –

+0

@MarcinOrlowski: Подход, который вы цитируете, заключался в том, чтобы явно избежать рекурсии. – hielsnoppe

ответ

0

Проверьте этот ключ для получения каждой клавиши и значения:

<?php 

error_reporting(0); 

$value = 'example'; 

$data = array(
    'foo' => 'bar', 
    'items' => array(array('foo' => 'bar','items' => array(array('foo' => 'bar')))) 
); 


$iterator = new RecursiveIteratorIterator(new RecursiveArrayIterator($data)); 
    foreach ($iterator as $k => $v) { 
     echo $k.'=>'.$v; 
     echo '</br>'; 
    } 

?> 

Форматирование было необходимо, но не хватило для минимальной длины редактирования. Поэтому я добавил этот иначе бесполезный текст.

+0

Это не делает, t нажимайте клавиши верхнего уровня, если у них есть вспомогательный массив. –

0

Для меня работает следующая рекурсивная функция. Обратите внимание, что он требует, чтобы передавать параметры по ссылке также внутри цикла foreach:

$value = 'example'; 

function do (&$item, $value) { 

    $item['baz'] = $value; 

    foreach ($item['items'] as &$next) { 

     do($next, $value); 
    } 
} 

foreach ($data['items'] as &$item) { 

    do($item, $value); 
} 
Смежные вопросы