關於簡單的方式獲取樹狀層級子孫樹的方案我已經寫過了,在這裏,當時是用簡單的遞歸實現的,但是現在回頭想想,如果層級很多,數據也很多,用遞歸感覺還是會不穩妥,這就有必要想辦法轉換爲迭代來實現了。
以下是迭代的代碼實現
<?php $data = [ ['id' => 1, 'name' => '中國', 'pid' => 0], ['id' => 2, 'name' => '江蘇', 'pid' => 1], ['id' => 6, 'name' => '工業園區', 'pid' => 5], ['id' => 7, 'name' => '中新大道', 'pid' => 6], ['id' => 9, 'name' => '鄞州區', 'pid' => 4], ['id' => 3, 'name' => '浙江', 'pid' => 1], ['id' => 10, 'name' => '天童南路', 'pid' => 8], ['id' => 8, 'name' => '首南街道', 'pid' => 9], ['id' => 4, 'name' => '寧波', 'pid' => 3], ['id' => 5, 'name' => '蘇州', 'pid' => 2], ['id' => 11, 'name' => '北京', 'pid' => 1], ['id' => 12, 'name' => '海淀', 'pid' => 11], ]; function getTree($data = [], $parent = 0) { $target_list = [$parent]; $tree = []; $level = 0; while (!empty($target_list)) { $flag = false; foreach ($data as $key => $value) { if ($value['pid'] == $parent) { $level++; $value['level'] = $level; $tree[] = $value; $target_list[] = $parent = $value['id']; unset($data[$key]); $flag = true; } } if (!$flag) { $level--; array_pop($target_list); $parent = end($target_list); } } return $tree; } $list = getTree($data, 0); foreach ($list as $v) { $level = isset($v['level']) ? $v['level'] : 0; echo str_repeat(' ', $level - 1) . $v['name'] . "\r\n"; }
輸出結果如下:
這裏我特意把傳遞的數據打亂順序,看看它能不能獲取到正確的順序層級,這樣一看也沒問題。
這個迭代的核心思想是用target_list去存儲當前要找的那個父級,找到了就追加進去,層級++,找不到就彈出來一個,層級--
可以看一下以前我寫遞歸的方式,遞歸就很好理解,但是自己心裏面就是感覺效率上和安全上面差點意思,代碼如下:
用數據庫的數據算了一下效率,其實差不多,沒有很明顯的差距,當數據量只有幾條的時候迭代比遞歸甚至還慢一點,當數據量有四千多條的時候(省市縣三級數據)迭代比遞歸稍微快一點點,但是真的不明顯。
看來這裏還需要一個更強更好的算法來解決該問題啊!