2015-06-27 113 views
0

我有以下陣列:(由PARENT_ID訂購)排序無限深度陣列 - PHP

array(9) { 
    [1]=> 
    array(3) { 
    ["name"]=> 
    string(6) "Tennis" 
    ["parent_id"]=> 
    NULL 
    ["depth"]=> 
    int(0) 
    } 
    [7]=> 
    array(3) { 
    ["name"]=> 
    string(11) "TOP LEVEL 2" 
    ["parent_id"]=> 
    NULL 
    ["depth"]=> 
    int(0) 
    } 
    [8]=> 
    array(3) { 
    ["name"]=> 
    string(11) "TOP LEVEL 3" 
    ["parent_id"]=> 
    NULL 
    ["depth"]=> 
    int(0) 
    } 
    [2]=> 
    array(3) { 
    ["name"]=> 
    string(5) "Shoes" 
    ["parent_id"]=> 
    string(1) "1" 
    ["depth"]=> 
    int(1) 
    } 
    [3]=> 
    array(3) { 
    ["name"]=> 
    string(5) "Women" 
    ["parent_id"]=> 
    string(1) "2" 
    ["depth"]=> 
    int(2) 
    } 
    [4]=> 
    array(3) { 
    ["name"]=> 
    string(4) "Mens" 
    ["parent_id"]=> 
    string(1) "2" 
    ["depth"]=> 
    int(2) 
    } 
    [5]=> 
    array(3) { 
    ["name"]=> 
    string(12) "Mens Running" 
    ["parent_id"]=> 
    string(1) "4" 
    ["depth"]=> 
    int(3) 
    } 
    [6]=> 
    array(3) { 
    ["name"]=> 
    string(11) "Mens Tennis" 
    ["parent_id"]=> 
    string(1) "4" 
    ["depth"]=> 
    int(3) 
    } 
    [9]=> 
    array(3) { 
    ["name"]=> 
    string(9) "2nd level" 
    ["parent_id"]=> 
    string(1) "8" 
    ["depth"]=> 
    int(1) 
    } 
} 

我想它的方式,它可以在下拉菜單中使用排序。下拉菜單的格式爲:

$categories[$CATEGORY_ID] = str_repeat('  ', $value['depth']).$value['name']; 

上面的數組頂部按parent_id排序,其中頂級的parent_id爲NULL。

我需要按照數組按順序排序。例如:

[1] => 'Tennis'; 
[2] => ' &nbspShoes' 
[3] => '     Womens' 
[4] => '     Men' 
[5] => '      Mens Running 
[6] => '      Mens Tennis 
[7] => 'TOP LEVEL 2' 
[8] => 'TOP LEVEL 3' 
[9] => '  2nd level' 

我嘗試這樣做:

function get_all_categories_and_subcategories($parent_id = NULL, $depth = 0) 
{ 
    $categories = $this->get_all($parent_id, 10000, 0, 'parent_id'); 

    if (!empty($categories)) 
    { 
     $unique_parent_ids = array(); 
     foreach($categories as $id => $value) 
     { 
      $categories[$id]['depth'] = $depth; 
      $unique_parent_ids[$id] = TRUE; 
     } 

     foreach(array_keys($unique_parent_ids) as $id) 
     { 
      $categories = array_replace($categories, $this->get_all_categories_and_subcategories($id, $depth + 1)); 
     } 

     return $categories; 
    } 
    else 
    {   
     return $categories; 
    } 
} 


function sort_categories($categories) 
{ 
    usort($categories, array('Category','do_sort_categories')); 
    return $categories; 
} 

static function do_sort_categories($a, $b) 
{ 
    $al = strtolower($a['parent_id']); 
    $bl = strtolower($b['parent_id']); 
    if ($al == $bl) { 
      return 0; 
    } 
    return ($al > $bl) ? +1 : -1; 
} 


function get_all($parent_id = NULL, $limit=10000, $offset=0,$col='name',$order='asc') 
{ 
    $this->db->from('categories'); 
    if (!$this->config->item('speed_up_search_queries')) 
    { 
     $this->db->order_by($col, $order); 
    } 

    if ($parent_id === NULL) 
    { 
     $this->db->where('parent_id IS NULL', null, false); 
    } 
    else if($parent_id) 
    { 
      $this->db->where('parent_id', $parent_id); 
    } 

    $this->db->limit($limit); 
    $this->db->offset($offset); 

    $return = array(); 

    foreach($this->db->get()->result_array() as $result) 
    { 
     $return[$result['id']] = array('name' => $result['name'], 'parent_id' => $result['parent_id']); 
    } 

    return $return; 
} 
+0

你到目前爲止試過了什麼?這不是一個編碼服務,所以你需要首先展示一個可靠的嘗試。我建議你閱讀[如何提出好問題](http://stackoverflow.com/help/how-to-ask)。 – Anonymous

+0

我試過ksort;但是這隻有在類別按順序創建時纔有效。我也試圖使用usort;但無法弄清楚。 –

+0

我已更新我的代碼。我試圖發佈代碼的隔離部分,因爲我已經完成了數據庫中的檢索部分;但也許可以修改? –

回答

1

我沒有現在來測試這個代碼的可能性,但如果需要的話,你可以嘗試這樣的事情(和正確的從我的意見)。

希望這會有所幫助。

$objects = array(); 
// turn to array of objects to make sure our elements are passed by reference 
foreach ($array as $k => $v) { 
    $node = new StdClass(); 
    $node->id = $k; 
    $node->parent_id = $v['parent_id']; 
    $node->name = $v['name']; 
    $node->depth = $v['depth']; 
    $node->children = []; 
    $objects[$k] = $node; 
} 
// list dependencies parent -> children 
foreach ($objects as $node) 
{ 
    $parent_id = $node->parent_id; 
    if ($parent_id !== null) 
    { 
     $object[$parent_id][] = $node; 
    } 
} 
// sort children of each node 
foreach ($objects as $node) 
{ 
    usort($node->children, function($a, $b){ 
     return $a->id < $b->id; 
    }); 
} 
// clean the object list to make kind of a tree (we keep only root elements) 
$sorted = array_filter($objects, function($node){ 
    return $node->depth === 0; 
}); 
// flatten recursively 
function flatten_node(&$node) { 
    return array_merge([$node], flatten($node->children)); 
} 
array_walk($sorted, 'flatten_node'); 
// $sorted is a sorted list of objects (not array as defined at the beginning). 
// You could turn it back to array and remove the 'children' key that was 
// only used for sorting purposes. 
+0

這讓我的80%的路上。會有幾個問題。當我做了flatten_node它永遠跑了;但我修改了一個扁平函數在http://stackoverflow.com/questions/26065557/php-flatten-array-and-add-depth-key。我也不需要像在數據庫查詢級別那樣進行排序。我也改變了'$ object [$ parent_id] [] = $ node; 'to'$ objects [$ parent_id] - > children [] = $ node;'因爲我認爲它是一個類型 –

+0

是的,我忘記了遞歸parttern中的結束條件。對我感到羞恥......並沒有將陣列節點作爲參數處理。修改它的好處!是的,這實際上是你發現的另一條線的錯字。很高興它幫助你。 – Mat

+0

你爲我提供了一個很好的起點。如果不是你的幫助,我不知道我會花多長時間。 –