1

给定一个多维数组或字典$array

并假设$array['foo']['bar']['baz'] = 'something';

除了通过 eval 语句对我来说,还有其他方法可以使用多维索引foo/bar/baz吗?(用例是动态创建索引,即函数不知道 /foo/bar/baz/ 是什么)。

我能想到的唯一方法是:

$item = testGetIndex($array, "'foo']['bar']['baz'");

function testGetIndex($array, $index) {
  eval('$item = $array[' . $index . '];');
  return $item;
}

注意:我应该提到我不想搜索这个数组。这是一个奇怪的用例。我被传递了一个非常大的多维数组,不得不使用像..

$array[foo][bar]..[baz]对数组进行修改。

4

3 回答 3

2

在这里公然重用我的答案

function recurseKeys(array $keys,array $array){
    $key = array_shift($keys);
    if(!isset($array[$key])) return null;
    return empty($keys) ?
        $array[$key]:
        recurseKeys($keys,$array[$key];
}
$values = recurseKeys(explode('/','foo/bar/baz'),$yourArray);

编辑:正如杰克指出的那样,不需要递归:

function findByKey(array $keys,array $array){
    while(!is_null($key = array_shift($keys))){
        if(!isset($array[$key])) return null;
        $array = $array[$key];
    }
    return $array;
}
$values = findByKey(explode('/','foo/bar/baz'),$yourArray);
于 2013-04-25T18:51:20.027 回答
1

一个简单的循环就可以做到,比如:

function get(array $array, $keys) {
  $val = $array;
  foreach (explode('/', $keys) as $part) {
    if (!isset($val[$part])) {
      return null;
    }
    $val = $val[$part];
  }
  return $val;
}

$array['foo']['bar']['baz'] = 'something';
echo get($array, 'foo/bar/baz');

http://ideone.com/vcRvXW

编辑

对于修改,只需使用引用:

function set(array &$array, $keys, $value) {
  $val = &$array;
  foreach (explode('/', $keys) as $part) {
    if (!isset($val[$part])) {
      $val[$part] = array();
    }
    $val = &$val[$part];
  }
  $val = $value;
}

http://ideone.com/WUNhF6

于 2013-04-25T18:54:05.693 回答
1

使用路径修改数组:

function setPath(&$root, $path, $value)
{
        $paths = explode('/', $path);
        $current = &$root;

        foreach ($paths as $path) {
                if (isset($current[$path])) {
                        $current = &$current[$path];
                } else {
                        return null;
                }
        }

        return $current = $value;
}
$path = 'foo/bar/baz';
$root = array('foo' => array('bar' => array('baz' => 'something')));

setPath($root, $path, '123');

您可以调整函数以仅返回对要更改的元素的引用:

function &getPath(&$root, $path)
{
        $paths = explode('/', $path);
        $current = &$root;

        foreach ($paths as $path) {
                if (isset($current[$path])) {
                        $current = &$current[$path];
                } else {
                        return null;
                }
        }

        return $current;
}

$x = &getPath($root, $path);

$x = 456; // $root['foo']['bar']['baz'] == 456
于 2013-04-25T18:53:15.633 回答