将分隔字符串转换为数组键路径并赋值

14

我有一个字符串:

$string = 'one/two/three/four';

我将其转换为一个数组:

$keys = explode('/', $string);

这个数组可以有任意数量的元素,例如1、2、5等。

如何在多维数组中分配特定的值,但使用上面创建的数组$keys来识别要插入的位置?

例如:

$arr['one']['two']['three']['four'] = 'value';

抱歉如果问题有点令人困惑,但我不知道怎样更好地解释它。


使用字符串路径设置嵌套数组数据,类似于PHP中的关联数组键路径吗?将字符串转换为关联数组键,如何将字符串转换为多维数组路径,PHP变量中的数组路径。 - mickmackusa
5个回答

16
这有点复杂,因为你想要嵌套,但应该按以下方式进行:

这是有关IT技术的内容。

function insert_using_keys($arr, $keys, $value){
    // we're modifying a copy of $arr, but here
    // we obtain a reference to it. we move the
    // reference in order to set the values.
    $a = &$arr;

    while( count($keys) > 0 ){
        // get next first key
        $k = array_shift($keys);

        // if $a isn't an array already, make it one
        if(!is_array($a)){
            $a = array();
        }

        // move the reference deeper
        $a = &$a[$k];
    }
    $a = $value;

    // return a copy of $arr with the value set
    return $arr;
}

9
$string = 'one/two/three/four';
$keys = explode('/', $string);
$arr = array(); // some big array with lots of dimensions
$ref = &$arr;

while ($key = array_shift($keys)) {
    $ref = &$ref[$key];
}

$ref = 'value';

这段代码的作用是:

  • 使用变量$ref来跟踪对$arr当前维度的引用。
  • 逐个遍历$keys,引用当前引用的$key元素。
  • 将值设置为最终引用。

当我尝试这个时,我收到了“服务器关闭连接”的消息 :) - Alex
如果$keys包含0或NULL会怎样? - Mark Elliot
他问如何解决问题,而不是为此编写错误检查 :) - FtDRbwLXw6
尽管有这些条件,解决问题仍然是可能的,但你的代码在那种情况下表现糟糕。 - Mark Elliot
2
$arr不是一个数组时,您的解决方案会“惨败”,还有其他一些情况。弹性的错误检查并不是正确答案的先决条件。 - FtDRbwLXw6
对于需要相同功能的任何人:我修改了这段精彩的代码,将$ref = &$ref['children'][$key]添加进去,因为我需要所有子节点都在一个数组子节点中。 - jasie

1

你需要先确保键存在,然后再分配值。类似这样的代码应该可以工作(未经测试):

function addValueByNestedKey(&$array, $keys, $value) {
    $branch = &$array;
    $key = array_shift($keys);
    // add keys, maintaining reference to latest branch:
    while(count($keys)) {
        $key = array_pop($keys);
        if(!array_key_exists($key, $branch) {
            $branch[$key] = array();
        }
        $branch = &$branch[$key];
    }
    $branch[$key] = $value;
}

// usage:
$arr = array();
$keys = explode('/', 'one/two/three/four');

addValueByNestedKey($arr, $keys, 'value');

1

虽然有点老套,但是:

function setValueByArrayKeys($array_keys, &$multi, $value) {
     $m = &$multi
     foreach ($array_keys as $k){
         $m = &$m[$k];
     }
     $m = $value;
}

这样行不通。$multi = $multi[$k] 创建了一个副本,而不是引用,所以当你执行 $multi = $value 时,你实际上并没有修改任何东西,除了最终的数组。 - Mark Elliot
它仍然无法工作,你正在创建副本而不是引用。 - Mark Elliot
抱歉兄弟,我是一个 Python 程序员,而默认情况下你会得到 Python 的引用。再次编辑过。 - MattoTodd
信不信由你,这仍然不能按照您的期望工作,将$multi作为参数传递会生成一个副本,您分配给$m的第一个引用是指向副本而不是原始数据。您可以(a)在参数列表中将$multi设置为引用或(b)return $multi - Mark Elliot
1
一般而言,如果您不熟悉目标语言,您应该运行您的代码。 - Mark Elliot

0
    $arr['one']['two']['three']['four'] = 'value';

    $string = 'one/two/three/four';
    $ExpCheck = explode("/", $string);
    $CheckVal = $arr;
    foreach($ExpCheck AS $eVal){
        $CheckVal = $CheckVal[$eVal]??false;
        if (!$CheckVal)
            break;
    }
    if ($CheckVal) {
        $val =$CheckVal;
    }

这将会返回数组中的值。


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