如何通过键名/路径访问和操作多维数组? [英] How to access and manipulate multi-dimensional array by key names / path?

查看:25
本文介绍了如何通过键名/路径访问和操作多维数组?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我必须在 PHP 中实现一个 setter,它允许我指定数组(目标)的键或子键,将名称作为点分隔键传递价值.

I've to implement a setter in PHP, that allows me to specify the key, or sub key, of an array (the target), passing the name as a dot-separated-keys value.

给定以下代码:

$arr = array('a' => 1,
             'b' => array(
                 'y' => 2,
                 'x' => array('z' => 5, 'w' => 'abc')
             ),
             'c' => null);

$key = 'b.x.z';
$path = explode('.', $key);

$key的值我想达到$arr['b']['x']['z'的值5].

From the value of $key I want to reach the value 5 of $arr['b']['x']['z'].

现在,给定一个变量值 $key 和一个不同的 $arr 值(具有不同的深度).

Now, given a variable value of $key and a different $arr value (with different deepness).

对于 getter get() 我写了这个代码:

For the getter get() I wrote this code:

public static function get($name, $default = null)
{
    $setting_path = explode('.', $name);
    $val = $this->settings;

    foreach ($setting_path as $key) {
        if(array_key_exists($key, $val)) {
            $val = $val[$key];
        } else {
            $val = $default;
            break;
        }
    }
    return $val;
}

编写 setter 比较困难,因为我成功地找到了正确的元素(来自 $key),但是我无法在原始数组,我不知道如何一次指定所有键.

To write a setter is more difficult because I succeed in reaching the right element (from the $key), but I am not able to set the value in the original array and I don't know how to specify the keys all at once.

我应该使用某种回溯吗?或者我可以避免它吗?

Should I use some kind of backtracking? Or can I avoid it?

推荐答案

假设 $path 已经是一个通过 explode 的数组(或者添加到函数中),那么你可以使用参考.您需要添加一些错误检查,以防 $path 等无效(想想 isset):

Assuming $path is already an array via explode (or add to the function), then you can use references. You need to add in some error checking in case of invalid $path etc. (think isset):

$key = 'b.x.z';
$path = explode('.', $key);

吸气剂

function get($path, $array) {
    //$path = explode('.', $path); //if needed
    $temp =& $array;

    foreach($path as $key) {
        $temp =& $temp[$key];
    }
    return $temp;
}

$value = get($path, $arr); //returns NULL if the path doesn't exist

设置者/创作者

如果您传递一个尚未定义的数组,则此组合将在现有数组中设置一个值或创建该数组.确保将 $array 定义为通过引用传递 &$array:

Setter / Creator

This combination will set a value in an existing array or create the array if you pass one that has not yet been defined. Make sure to define $array to be passed by reference &$array:

function set($path, &$array=array(), $value=null) {
    //$path = explode('.', $path); //if needed
    $temp =& $array;

    foreach($path as $key) {
        $temp =& $temp[$key];
    }
    $temp = $value;
}

set($path, $arr);
//or
set($path, $arr, 'some value');

Unsetter

这将取消设置路径中的最后一个键:

function unsetter($path, &$array) {
    //$path = explode('.', $path); //if needed
    $temp =& $array;

    foreach($path as $key) {
        if(!is_array($temp[$key])) {
            unset($temp[$key]);
        } else {
            $temp =& $temp[$key];
        }
    }
}
unsetter($path, $arr);

*最初的答案有一些有限的功能,我会留下这些功能,以防它们对某人有用:

二传手

确保将$array定义为通过引用传递&$array:

Make sure to define $array to be passed by reference &$array:

function set(&$array, $path, $value) {
    //$path = explode('.', $path); //if needed
    $temp =& $array;

    foreach($path as $key) {
        $temp =& $temp[$key];
    }
    $temp = $value;
}

set($arr, $path, 'some value');

或者如果你想返回更新后的数组(因为我很无聊):

Or if you want to return the updated array (because I'm bored):

function set($array, $path, $value) {
    //$path = explode('.', $path); //if needed
    $temp =& $array;

    foreach($path as $key) {
        $temp =& $temp[$key];
    }
    $temp = $value;

    return $array;
}

$arr = set($arr, $path, 'some value');

创作者

如果您不想创建数组并可选择设置值:

If you wan't to create the array and optionally set the value:

function create($path, $value=null) {
    //$path = explode('.', $path); //if needed
    foreach(array_reverse($path) as $key) {
        $value = array($key => $value);
    }
    return $value;
}    

$arr = create($path);    
//or
$arr = create($path, 'some value');

为了好玩

构造和计算类似 $array['b']['x']['z'] 给定的字符串 b.x.z:

Constructs and evaluates something like $array['b']['x']['z'] given a string b.x.z:

function get($array, $path) {
    //$path = explode('.', $path); //if needed
    $path = "['" . implode("']['", $path) . "']";
    eval("\$result = \$array{$path};");

    return $result;
}

设置类似 $array['b']['x']['z'] = 'some value';:

function set(&$array, $path, $value) {
    //$path = explode('.', $path); //if needed
    $path = "['" . implode("']['", $path) . "']";
    eval("\$array{$path} = $value;");
}

取消设置类似$array['b']['x']['z']:

function unsetter(&$array, $path) {
    //$path = explode('.', $path); //if needed
    $path = "['" . implode("']['", $path) . "']";
    eval("unset(\$array{$path});");
}

这篇关于如何通过键名/路径访问和操作多维数组?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆