2010-10-21 71 views
1

我有類別的數組:排序分類用PHP陣列

categories = computers, entertainment, products, graphics cards 

陣列被以錯誤的順序有時返回,但每一類具有存在相同的陣列中的父節點。

categories = 
products[parent=0], 
entertainment[parent=products], 
computers[parent=entertainment], 
graphics cards[parent=computers] 

如果以任何順序返回,我將如何使用php對此數組進行排序?

無序例子:

categories = 
computers[parent=entertainment], 
entertainment[parent=products], 
products[parent=0], 
graphics cards[parent=computers]  

必須出示:

categories = products, entertainment, computers, graphics cards 
+0

你說喲你想做一個拓撲排序? – 2010-10-21 19:30:14

+1

這是某種*如何從代表分層數據的數據庫記錄構建分層數組?*問題? – Gumbo 2010-10-21 19:30:19

+0

它是,但類別數組不是以正確的順序返回。 – InnateDev 2010-10-21 19:55:26

回答

0

你說的是一個簡單的排序是這樣的:

<?php 


$categories = array('computers[parent=entertainment]', 
'entertainment[parent=products]', 
'products[parent=0]', 
'graphics cards[parent=computers]'); 
sort($categories); 
echo '<pre>'; 
print_r($categories); 
echo '</pre>'; 

?> 
0

看着你的榜樣,我假設正如Sam Dufel所說,你需要一種拓撲排序。

$categories = array(
    "computers" => array("parent" => "entertainment"), 
    "entertainment" => array("parent" => "products"), 
    "products" => array("parent" => null), 
    "graphics cards" => array("parent" => "computers") 
); 

// Set distances 
foreach ($categories as $cat => &$e) { 
    $e["dist"] = nodeDistance($cat, $categories); 
} 

// Before 
echo implode(", ", array_keys($categories)) . "\n"; 
// Sort 
uasort($categories, "nodeDistanceSorter"); 
// After 
echo implode(", ", array_keys($categories)) . "\n"; 

function nodeDistance($node, $categories) { 
    // Check cache 
    if (array_key_exists("dist", $categories[$node])) 
     return $categories[$node]["dist"]; 
    // Check root 
    if (is_null($categories[$node]["parent"])) 
     return 0; 
    // Traverse 
    return nodeDistance($categories[$node]["parent"], $categories) + 1; 
} 

function nodeDistanceSorter($a, $b) { 
    $aDist = $a["dist"]; 
    $bDist = $b["dist"]; 
    if ($aDist == $bDist) 
     return 0; 
    return $aDist - $bDist; 
} 
0
categories = 
products[parent=0], 
entertainment[parent=products], 
computers[parent=entertainment], 
graphics cards[parent=computers] 

我認爲該陣列是這樣的:

$categories = array 
(
    'products'=>array('parent'=>0),//poor little orphan 
    'entertainment'=>array('parent'=>'products'), 
    'computers'=>array('parent'=>'entertainment'), 
    'graphics cards'=>array('parent'=>'computers'), 
) 

這裏是一個解決方案,我現在混合起來:

溶液1

$categories = array 
(
'computers'=>array('parent'=>'entertainment'), 
'entertainment'=>array('parent'=>'products'), 
'products'=>array('parent'=>0), 
'graphics cards'=>array('parent'=>'computers') 
); 

function addparentfirst(&$original,$array,$name,$data){ 
    if(isset($data['parent']) && isset($original[$data['parent']])){ 
     $array = addparentfirst($original,$array,$data['parent'],$original[$data['parent']]); 
    } 
    $array[$name] = $data; 
    unset($original[$name]); 
    return $array; 
} 
foreach($categories as $key=>$value){//goes over each category only once, contrary to what it looks like 
    $sortedcategories = addparentfirst($categories,$sortedcategories,$key,$value); 
} 
$categories = $sortedcategories;//NOW IT'S SORTED 

print_r($categories); 

解決方案2

//It's interesting that it doesn't loop infinitely 
//I like this solution the most 

function addparentfirst(&$array,$key){ 
    if(isset($array[$key]['parent']) && !empty($array[$key]['parent'])){ 
     addparentfirst($array,$array[$key]['parent']); 
    } 
    $data = $array[$key]; 
    unset($array[$key]); 
    $array[$key] = $data; 
    return $array; 
} 


foreach($categories as $key=>$value){ 
    addparentfirst($categories,$key); 
} 
print_r($categories); 

解決方案3

function sortArrayByArray($array,$orderArray) { 
    $ordered = array(); 
    foreach($orderArray as $key) { 
     if(isset($array[$key])) { 
       $ordered[$key] = $array[$key]; 
       unset($array[$key]); 
     } 
    } 
    return $ordered + $array; 
} 



//Usage: 
$categories = sortArrayByArray($categories,array('products','entertainment','computers','graphics cards')); 
print_r($categories); 

as seen here

解決方案4

function get_childless_category_name($array){ 
    foreach($array as $key=>$value){ 
     if(isset($value['parent']) && !empty($value['parent'])){ 
      unset($array[$value['parent']]); 
     } 
    } 
    $names = array_keys($array);//names of all the child free categories 
    return array_pop($names);//get the last one (there should only be one) 
} 
function parent_comes_first(&$array,$key){ 
    if(isset($array[$key]['parent']) && !empty($array[$key]['parent'])){ 
     $array = parent_comes_first($array,$array[$key]['parent']); 
    } 
    $data = $array[$key]; 
    unset($array[$key]); 
    $array[$key] = $data; 
    return $array; 
} 


//Usage: 
$childless = get_childless_category_name($categories); 
parent_comes_first($categories,$childless); 

print_r($categories);