将多维数组解析为完全指定的端点

Posted

技术标签:

【中文标题】将多维数组解析为完全指定的端点【英文标题】:Resolve a multi dimensional array into fully specified endpoints 【发布时间】:2022-01-05 21:27:25 【问题描述】:

我需要使用 php 将多维数组(任意维度)中的每个端点转换为包含所有后代节点的行。换句话说,我想解析数组中的每个完整分支。我不确定如何更清楚地说明这一点,所以最好的方法是举个例子。

如果我从这样的数组开始:

$arr = array(
 'A'=>array(
    'a'=>array(
        'i'=>1, 
        'j'=>2),
    'b'=>3
 ),
 'B'=>array(
    'a'=>array(
        'm'=>4, 
        'n'=>5),
    'b'=>6
 )
);

数组中有6个端点,即数字1到6,我想将6行生成为:

    A,a,i,1 A,a,j,2 A,b,2 B,a,m,3 B,a,n,4 B,b,2

每一行都包含到终点的后代的完整路径。由于数组可以有任意数量的维度,这建议使用递归 PHP 函数,我尝试了:

function array2Rows($arr, $str='', $out='') 
  if (is_array($arr)) 
    foreach ($arr as $att => $arr1) 
        $str .= ((strlen($str)? ',': '')) . $att;
        $out = array2Rows($arr1, $str, $out);
    
    echo '<hr />';
   else 
    $str .= ((strlen($str)? ',': '')) . $arr;
    $out .= ((strlen($out)? '<br />': '')) . $str;
  
  return $out;

函数调用如下:

echo '<p>'.array2Rows($arr, '', '').'</p>';

这个函数的输出是:

    A,a,i,1 A,a,i,j,2 A,a,b,3 A,B,a,m,4 A,B,a,m,n,5 A,B,a,b,6

除了第一个值之外,这是不正确的,因为某些节点上的值是重复的。我已经尝试了递归函数的多种变体,这是我能得到的最接近的。

我会欢迎任何关于如何解决这个问题的建议,如果问题的陈述不是很清楚,我会道歉。

【问题讨论】:

你需要什么输出? Walk array recursively and print the path of the walk, Recursively cycle every path of an array 【参考方案1】:

你的功能如此接近......我把你的功能和修改如下:

function array2Rows($arr, $str='', $csv='') 
    $tmp = $str;
    if (is_array($arr)) 
        foreach ($arr as $att => $arr1) 
            $tmp = $str . ((strlen($str)? ', ': '')) . $att;
            $csv = array2Rows($arr1, $tmp, $csv);
        
     else 
        $tmp .= ((strlen($str)? ', ': '')) . $arr;
        $csv .= ((strlen($csv)? '<br />': '')) . $tmp;
    
    return $csv;

唯一的区别是引入了一个临时变量 $tmp 以确保在每次运行递归函数之前不会更改 $str 值。

函数的输出变为:

这是一个很好的功能,我可以想到一些应用程序。

【讨论】:

【参考方案2】:

您重复倒数第二个值的原因是,在您的循环中,您在对下一个数组运行函数之前附加了键。这样的事情会更好:

function array2Rows($arr, &$out=[], $row = []) 
  if (is_array($arr)) 
    foreach ($arr as $key => $newArray)         
        if (is_array($newArray)) 
            $row[] = $key; //If the current value is an array, add its key to the current row
            array2Rows($newArray, $out, $row); //process the new value
         else  //The current value is not an array
            $out[] = implode(',',array_merge($row,[$key,$newArray])); //Add the current key and value to the row and write to the output    
        
         
  
  return $out;

这是经过轻微优化的,并利用引用来保存完整输出。我也将其更改为使用并返回一个数组而不是字符串。我发现这两项更改都使函数更具可读性。

如果您希望它返回格式与您的函数中的字符串类似的字符串,请将最后一行替换为

return implode('<br>', $out);

或者,您可以在调用时这样做,这就是我所说的此类事情的“最佳实践”;例如

$result = array2Rows($arr);
echo implode('<br>', $result);

注意,由于这使用了输出的引用,所以这也有效:

array2Rows($arr, $result);
echo implode('<br>', $result); 

【讨论】:

感谢您在这方面的帮助,我无法告诉您我花了多少时间尝试逐步解决问题以找出问题所在。我很欣赏数组输出,因为这也可能有用。 很高兴我能提供帮助,如果这符合您的需要,请随时将其标记为正确答案。

以上是关于将多维数组解析为完全指定的端点的主要内容,如果未能解决你的问题,请参考以下文章

将多维数组格式的查询字符串解析为实际数组

将 json 转换为多维 PHP 数组

创建具有未指定可变行长度的多维数组(Java)

解析没有键的多维 JSON 数组

在 Symfony2 中将多维数组转换为点表示法

python如何减小维度