从关联数组获取嵌套值

发布于 2024-10-26 01:18:15 字数 1094 浏览 1 评论 0原文

这是一个一般性的实施问题。如果我有一个任意深的数组,并且我事先不知道键是什么,那么访问关联数组特定路径处的值的最佳方法是什么?例如,给定数组:访问

array(
    'great-grandparent' = array(
        'grandparent' = array(
             'parent' = array(
                  'child' = 'value';
              ),
              'parent2' = 'value';
         ),
         'grandparent2' = 'value';
    )
);

$array['great-grandparent']['grandparent']['parent']['child'] 处的值的最佳方式是什么?请记住我事先不知道钥匙。我使用 eval 将上述语法构造为带有变量名称的字符串,然后对字符串进行 eval 来获取数据。但 eval 很慢,我希望有更快的东西。类似于 $class->getConfigValue('great-grandparent/grandparent/'.$parent.'/child'); 的内容将返回 'value'

评估代码示例

public function getValue($path, $withAttributes=false) {
        $path = explode('/', $path);
        $rs = '$r = $this->_data[\'config\']';
        foreach ($path as $attr) {
            $rs .= '[\'' . $attr . '\']';
        }
        $rs .= ';';
        $r = null;
        @eval($rs);
        if($withAttributes === false) {
            $r = $this->_removeAttributes($r);
        }
        return $r;
    }

This is sort of a general implementation question. If I have an arbitrarily deep array, and I do not know before hand what the keys will be, what is the best way to access the values at specific paths of the associative array? For example, given the array:

array(
    'great-grandparent' = array(
        'grandparent' = array(
             'parent' = array(
                  'child' = 'value';
              ),
              'parent2' = 'value';
         ),
         'grandparent2' = 'value';
    )
);

Whats the best way to access the value at $array['great-grandparent']['grandparent']['parent']['child'] keeping in mind that I don't know the keys beforehand. I have used eval to construct the above syntax as a string with variable names and then eval'd the string to get the data. But eval is slow and I was hoping for something faster. Something like $class->getConfigValue('great-grandparent/grandparent/'.$parent.'/child'); that would return 'value'

Example of Eval Code

public function getValue($path, $withAttributes=false) {
        $path = explode('/', $path);
        $rs = '$r = $this->_data[\'config\']';
        foreach ($path as $attr) {
            $rs .= '[\'' . $attr . '\']';
        }
        $rs .= ';';
        $r = null;
        @eval($rs);
        if($withAttributes === false) {
            $r = $this->_removeAttributes($r);
        }
        return $r;
    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

诗笺 2024-11-02 01:18:15

我不知道潜在的速度,但你不需要使用 eval 进行这样的搜索:

  $conf = array(
      'great-grandparent' => array(
          'grandparent' => array(
               'parent' => array(
                    'child' => 'value searched'
                ),
                'parent2' => 'value'
           ),
           'grandparent2' => 'value'
      )
  );

  $path = 'great-grandparent/grandparent/parent/child';
  $path = explode('/', $path);

  $result = $conf;

  while(count($path) > 0) {
      $part = array_shift($path);

      if (is_array($result) && array_key_exists($part, $result)) {
          $result = $result[$part];
      } else {
          $result = null;
          break;
      }
  }

  echo $result;

I don't know about the potential speed but you don't need to use eval to do a search like that :

  $conf = array(
      'great-grandparent' => array(
          'grandparent' => array(
               'parent' => array(
                    'child' => 'value searched'
                ),
                'parent2' => 'value'
           ),
           'grandparent2' => 'value'
      )
  );

  $path = 'great-grandparent/grandparent/parent/child';
  $path = explode('/', $path);

  $result = $conf;

  while(count($path) > 0) {
      $part = array_shift($path);

      if (is_array($result) && array_key_exists($part, $result)) {
          $result = $result[$part];
      } else {
          $result = null;
          break;
      }
  }

  echo $result;
梦归所梦 2024-11-02 01:18:15

来吧,我的解决方案:

$tree = array(
    'great-grandparent' => array(
        'grandparent' => array(
             'parent' => array(
                  'child' => 'value1'
              ),
              'parent2' => 'value2'
         ),
         'grandparent2' => 'value3'
    )
);

$pathParts = explode('/','great-grandparent/grandparent/parent/child');
$pathParts = array_reverse($pathParts);

echo retrieveValueForPath($tree, $pathParts);

function retrieveValueForPath($node, $pathParts)  {
    foreach($node as $key => $value) {
        if(($key == $pathParts[count($pathParts)-1]) && (count($pathParts)==1)) {
            return $value;
        }       

        if($key == $pathParts[count($pathParts)-1]) {
            array_pop($pathParts);
        }

        if(is_array($value)) {
            $result = retrieveValueForPath($value, $pathParts);
        }
    }

    return $result;
}

Here we go, my solution:

$tree = array(
    'great-grandparent' => array(
        'grandparent' => array(
             'parent' => array(
                  'child' => 'value1'
              ),
              'parent2' => 'value2'
         ),
         'grandparent2' => 'value3'
    )
);

$pathParts = explode('/','great-grandparent/grandparent/parent/child');
$pathParts = array_reverse($pathParts);

echo retrieveValueForPath($tree, $pathParts);

function retrieveValueForPath($node, $pathParts)  {
    foreach($node as $key => $value) {
        if(($key == $pathParts[count($pathParts)-1]) && (count($pathParts)==1)) {
            return $value;
        }       

        if($key == $pathParts[count($pathParts)-1]) {
            array_pop($pathParts);
        }

        if(is_array($value)) {
            $result = retrieveValueForPath($value, $pathParts);
        }
    }

    return $result;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文