2016-12-10 56 views
0

我有带数据的结构化数组,需要将附加数据附加到节点X.节点X由其他数组($ path)中的路径指定。在树中的某个特定位置包含新数据

$data = [ 
183013 => 
    [ 
     183014 => [ 
      183018, 
      183019 => [ 
       183021, 
       183022 => [ 
        183023 
       ] 
      ], 
      183020 
     ], 
     183016, 
     183017 
    ] 
]; 

$path = [183013, 183014, 183019, 183021]; 
$new_data = [183030 => [183031]]; 

所以,我需要$ NEW_DATA追加到元素183021. 的$深度数据或$路径是无限的。

+0

所有的编号是唯一的,正确的? – RomanPerekhrest

+0

你可以尝试通过搜索和使用array_push方法 – C2486

+0

我认为这些数字不是唯一的 – EugenA

回答

1

有了一些时间对phplab.io/lab/iwnXI

打我创造了这个:

数据

<?php 
$data = [ 
    183013 => [ 
     183014 => [ 
      183018, 
      183019 => [ 
       183021, 
       183022 => [ 
        183023 
       ] 
      ], 
      183020 
     ], 
     183016, 
     183017 
    ] 
]; 

$path = [183013, 183014, 183019, 183021]; 

$new_data = [183030 => [183031]]; 

解决方案1 ​​ - 递归函数

提供数据功能,并且每个节点都将被添加。 我们需要以除去最终的数字值(即, '0 => 183020')

<?php function appendIntoArrayTree(array $source, array $path, array $values) { 
    $key = array_shift($path); 

    if (isset($source[$key]) && is_array($source[$key])) { 
     $source[$key] = appendIntoArrayTree($source[$key], $path, $values); 
    } 
    else { 
     // search if the current $path key exist as 'value' on the $source (i.e.: '0 => 183021') 
     if(!is_null($foundKey = array_search($key, $source))) { 
      unset($source[$foundKey]); 
     } 
     $source[$key] = $values; // final 
    } 

    return $source; 
} 

和输出:

var_dump(appendIntoArrayTree($data, $path, $new_data)); 

解决方案2 - EVAL模式

这是一个特技,和我不鼓励使用它(另外一些服务器不允许使用eval()

function appendIntoArrayTreeWithEval(array $source, array $path, array $values) { 
    $path_last = $path[count($path) - 1]; 
    $path_string = implode('', 
     array_map(function($v) { 
     return '[' . $v . ']'; 
     }, array_slice($path, 0, count($path) - 1)) 
    ); // Convert $path = ['a', 'b', 'c'] to string [a][b] (last 'c' not used) 

    $tmp = null; 
    eval('$tmp = isset($source' . $path_string . ') ? $source' . $path_string . ' : null;'); 
    if(is_null($tmp)) { 
     // $source[a][b] does not exists 
     eval('$source' . $path_string . '[' . $path_last . '] = $values;'); 
    } 
    else if(is_array($tmp)) { 
     if(!is_null($key = array_search($path_last, $tmp))) { 
      // key exists with 'numeric' array key value (0 =>, 1 =>, ...) 
      eval('unset($source' . $path_string . '[' . $key . ']);'); // remove 
     } 
     eval('$source' . $path_string . '[' . $path_last . '] = $values;'); 
    } else { 
     // is string/numeric/... Error. SHould not use 0/1/2 ... values 
    } 
    return $source; 
} 

和输出

var_dump(appendIntoArrayTreeWithEval($data, $path, $new_data)); 

解决方案1是最好的:)

(我们也尝试array merge recursive功能,但它不工作)

相关问题