2011-01-02 2 views
5

У меня есть результирующий набор в виде массива из базы данных, которая выглядит как:PHP манипулируя многомерный массив значений

array (
    0 => array (
     "a" => "something" 
     "b" => "something" 
     "c" => "something" 
    ) 
    1 => array (
     "a" => "something" 
     "b" => "something" 
     "c" => "something" 
    ) 
    2 => array (
     "a" => "something" 
     "b" => "something" 
     "c" => "something" 
    ) 
) 

Как бы применить функцию для замены значений массива только от ключа массива с б ? Обычно я просто перестраивал новый массив с циклом foreach и применял бы эту функцию, если ключ массива - b, но я не уверен, что это лучший способ. Я попытался взглянуть на многие функции массива, и казалось, что array_walk_recursive - это то, что я могу использовать, но мне не повезло, что он сделал то, что я хочу. Если я не описывая его достаточно хорошо, в основном я хочу, чтобы быть в состоянии сделать, как код ниже делает:

$arr = array(); 
foreach ($result as $key => $value) 
{ 
    foreach ($value as $key2 => $value2) 
    { 
     $arr[$key][$key2] = ($key2 == 'b' ? $this->_my_method($value2) : $value2); 
    }  
} 

Должен ли я придерживаться этого, или есть способ лучше?

ответ

3

array_walk_recursive Использование:

Если у вас есть PHP> = 5.3.0 (для anonymous functions):

array_walk_recursive($result, function (&$item, $key) { 
    if ($key == 'b') { 
     $item = 'the key is b!'; 
    } 
}); 

В противном случае что-то вроде:

function _my_method(&$item, $key) { 
    if ($key == 'b') { 
     $item = 'the key is b!'; 
    } 
} 
array_walk_recursive($result, '_my_method'); 
+0

Спасибо, я уже пробовал array_walk_recursive, как я сказал выше, но это не сработало. Видимо, я забыл разместить амперсанд перед параметром $ item! Работаю сейчас. – Joker

+0

Yup, простой ошибка. Цитирование руководства: 'Если funcname должно работать с фактическими значениями массива, укажите первый параметр funcname как ссылку. Затем любые изменения, внесенные в эти элементы, будут сделаны в самом исходном массиве. « – thirtydot

0

Непрошеный, но я думаю, что это сработает.

function replace_b (&$arr) 
{ 
    foreach ($arr as $k => $v) 
    { 
     if ($k == 'b') 
     { 
      /* Do something */ 
     } 
     if (is_array($v) 
     { 
      replace_b($arr[$k]); 
     } 
    } 
} 

Функция будет двигаться через массив проверки ключей для b. Если ключ указывает на массив, он рекурсивно следует за ним.

+0

Это не то, что 'array_walk_recursive' уже делает? –

+0

@Jacob: Я не знаком с точным синтаксисом 'array_walk_recursive' и не стал искать его. Ввод этого был быстрее. –

0

использования array_walk_recursive documented here

$replacer = function($x) {return "I used to be called $x";}; //put what you need here 
$replaceB = function(&$v, $k) use ($replacer) {if ($k === 'b') $v = $replacer($v);}; 

array_walk_recursive($arr, $replaceB); 

replacer функция может быть overkill. Вы можете заменить его буквальным или любым, что вам нравится.

+0

Я не уверен, почему кто-то решил понизить ваш ответ - это сработало для меня. Я бы рекомендовал его очистить, то есть упомянуть, что ключ должен передать $ v в качестве ссылки и изменить код для печати начальных и конечных значений и, конечно же, облегчить чтение (не используя ненужные лямбда-функции или дополнительную логику, например '$ k == 'b''). –

Смежные вопросы