PHP操作多维数组值

5

我有一个来自数据库的数组结果集,看起来像这样:

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"
    )
)

我该如何将一个函数应用于仅具有键b的数组值以替换它们?通常我会使用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个回答

5

使用array_walk_recursive函数:

如果你的PHP版本大于等于5.3.0(支持匿名函数):

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');

谢谢,我已经尝试过array_walk_recursive了,就像我之前说的那样,但它没有起作用。显然,我忘记在$item参数之前放置&符号了!现在可以工作了。 - Joker
是的,这是一个容易犯的错误。引用手册上的话:“如果 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。如果该键指向一个数组,则会递归地向下跟随它。

@Jacob:我不熟悉array_walk_recursive的确切语法,也没有去查找。打这段话比查找更快。 - Josh K
我想知道使用array_walk_recursive与循环+调用相同函数之间的性能差异。就像@JacobRelkin一样,我习惯于使用循环+调用相同函数,过去它一直运行良好。 - itsdarrylnorris

0

使用array_walk_recursive在此处有文档记录

$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函数可能有些过度。你可以用字面值或任何你喜欢的东西来替换它。


我不确定为什么有人决定对你的答案进行负投票 - 它对我起作用了。但是,我建议你清理一下,即提到关键是将 $v 作为引用传递,并更改代码以打印开始和结束值,当然还要使其更易于阅读(不使用不必要的 lambda 函数或额外的逻辑,如 $k == 'b')。 - wtf8_decode

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接