使用php数组排序类别

时间:2010-10-21 19:27:01

标签: php arrays sorting

我有一系列类别:

categories = computers, entertainment, products, graphics cards

有时以错误的顺序返回数组但是每个类别都有一个存在于SAME数组中的父类。

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

3 个答案:

答案 0 :(得分: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>';

?>

答案 1 :(得分: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;
}

答案 2 :(得分: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);