【问题标题】:Set multi-dimensional array by key path from array values?通过数组值的键路径设置多维数组?
【发布时间】:2010-06-29 21:56:11
【问题描述】:

对不起,糟糕的标题,我当时能想到的最好的!假设我有一个像这样的“路径”数组;

array('this', 'is', 'the', 'path')

最终得到以下数组的最有效方法是什么?

array(
    'this' => array(
        'is' => array(
            'the' => array(
                'path' => array()
            )
        )
    )
)

【问题讨论】:

  • 您想通过该路径获取值、设置值还是构建这样的结构?

标签: php arrays


【解决方案1】:

只需使用类似 array_shift 或 array_pop 的东西对其进行迭代:

$inarray = array('this', 'is', 'the', 'path',);
$tree = array();
while (count($inarray)) {
    $tree = array(array_pop($inarray) => $tree,);
}

未经测试,但这是它的基本结构。递归也很适合这个任务。 或者,如果您不想修改初始数组:

$inarray = array('this', 'is', 'the', 'path',);
$result = array();
foreach (array_reverse($inarray) as $key)
    $result = array($key => $result,);

【讨论】:

    【解决方案2】:

    我使用两个类似的函数通过它们在数组中的路径来获取和设置值:

    function array_get($arr, $path)
    {
        if (!$path)
            return null;
    
        $segments = is_array($path) ? $path : explode('/', $path);
        $cur =& $arr;
        foreach ($segments as $segment) {
            if (!isset($cur[$segment]))
                return null;
    
            $cur = $cur[$segment];
        }
    
        return $cur;
    }
    
    function array_set(&$arr, $path, $value)
    {
        if (!$path)
            return null;
    
        $segments = is_array($path) ? $path : explode('/', $path);
        $cur =& $arr;
        foreach ($segments as $segment) {
            if (!isset($cur[$segment]))
                $cur[$segment] = array();
            $cur =& $cur[$segment];
        }
        $cur = $value;
    }
    

    然后你像这样使用它们:

    $value = array_get($arr, 'this/is/the/path');
    $value = array_get($arr, array('this', 'is', 'the', 'path'));
    array_set($arr, 'here/is/another/path', 23);
    

    【讨论】:

      【解决方案3】:
      function buildArrayFromPath( $path ) {
        $out = array();
        while( $pop = array_pop($path) ) $out = array($pop => $out);
        return $out;
      }
      

      【讨论】:

        【解决方案4】:

        一种递归解决方案:

        function find_in_array(&$array, &$path, $_i=0) {
          // sanity check
          if ( !(is_array($array) && is_array($path)) ) return false;
          $c = count($path); if ($_i >= $c) return false;
        
          $k = $path[$_i];
          if (array_key_exists($k, $array))
            return ($_i == $c-1) ? $array[$k] : find_in_array($array[$k], $path, $_i+1);
          else
            return false;
        }
        

        参数$_i内部使用,调用函数时不要设置。

        【讨论】:

          【解决方案5】:

          不是很优雅。但它有效

          $start = array('this', 'is', 'the', 'path')

          $result[ $start[0] ][ $start[1] ][ $start[2] ][ $start[3] ] = array ();

          【讨论】:

          • 问题是,这只适用于预定义的数组计数 - 如果我不知道路径中有多少个节点怎么办?
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2014-05-20
          • 2012-01-05
          • 2015-06-24
          • 2021-10-27
          相关资源
          最近更新 更多