我需要使用 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
- 乙,乙,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
除了第一個值之外,這是不正確的,因為某些節點上的值是重復的。我已經嘗試了遞回函式的許多變體,這是我能得到的最接近的。
我歡迎任何關于如何解決這個問題的建議,如果問題的陳述不是很清楚,我會道歉。
uj5u.com熱心網友回復:
您重復倒數第二個值的原因是在回圈中您在下一個陣列上運行該函式之前附加鍵。像這樣的事情會更好:
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);
uj5u.com熱心網友回復:
你和你的函式非常接近......我把你的函式和修改如下:
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 值。
您的函式的輸出變為:

這是一個很好的功能,我可以想到一些應用程式。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/371668.html
上一篇:遞回求解網格的演算法
