使用 usort() 对具有分层排序条件的二维数组进行排序



尝试按披萨配料所属的类别对披萨配料的二维数组进行排序。但是客户端提供数据的方式并不理想。下面是数据示例:

        [0] => Array
            (
                [id] => 30
                [title] => Pepperoni
                [meat] => 1
                [veggie] => 
                [sauce] => 
                [cheese] => 
                [condiment] => 
            )
        [1] => Array
            (
                [id] => 29
                [title] => Onions
                [meat] => 
                [veggie] => 1
                [sauce] => 
                [cheese] => 
                [condiment] => 
            )

这个想法是浇头应始终按类型分组(即。 meat ) 按特定顺序(即。 meats后跟veggies后跟sauces等)— 与检索顺序无关。重要的是,没有浇头属于两种类型。

这是我对此的刺痛:

$topping_options = array()  // ie. the sample data above
usort($topping_options,
                function($opt_a, $opt_b) {
                    $scores = array("a" =>  0, "b" => 0);
                    foreach( array("a" => $opt_a, "b" => $opt_b) as $index => $opt) {
                        if ($opt['meat']) $scores[$index] = 5;
                        if ($opt['veggie']) $scores[$index] = 4;
                        if ($opt['sauce']) $scores[$index] = 3;
                        if ($opt['cheese']) $scores[$index] = 2;
                        if ($opt['condiment']) $scores[$index] = 1;
                    }
                    return $scores['a'] - $scores['b'];
                }
            );

这根本无法实现我的目标,我不明白为什么;在我看来,每当$opt_a的分数高于$opt_b时,它应该保持自己的位置,而$opt_b则被送下一级进行进一步比较。想了解我做错了什么。谢谢。

  1. 我认为您的代码是正确的,并且在测试数据中存在问题。对它们重新排序以查看结果
  2. 要获得正确的结果顺序,请将代码更改为

    返回 $scores['b'] - $scores['a'];

这是处理这种情况的一种方法。我刚刚将所有浇头分成自己的数组,然后在最后将它们合并在一起:

<?php
$toppings = array(
    array('id'=>1,'title'=>'M1','meat'=>1,'veggie'=>NULL,'sauce'=>NULL,'cheese'=>NULL,'condiment'=>NULL),
    array('id'=>2,'title'=>'V1','meat'=>NULL,'veggie'=>1,'sauce'=>NULL,'cheese'=>NULL,'condiment'=>NULL),
    array('id'=>3,'title'=>'M2','meat'=>1,'veggie'=>NULL,'sauce'=>NULL,'cheese'=>NULL,'condiment'=>NULL),
    array('id'=>4,'title'=>'V2','meat'=>NULL,'veggie'=>1,'sauce'=>NULL,'cheese'=>NULL,'condiment'=>NULL),
    array('id'=>5,'title'=>'M3','meat'=>1,'veggie'=>NULL,'sauce'=>NULL,'cheese'=>NULL,'condiment'=>NULL)
);
$categories = array(
    'meat',
    'veggie',
    'sauce',
    'cheese',
    'condiment'
);
$segregated_toppings = array();
foreach($toppings as $topping){
    foreach($categories as $c){
        if($topping[$c]){
            if(!isset($segregated_toppings[$c])){
                $segregated_toppings[$c] = array();
            }
            $segregated_toppings[$c][] = $topping;
        }
    }
}
#echo '<pre>',print_r($segregated_toppings),'</pre>';
$sorted_array = call_user_func_array('array_merge',$segregated_toppings);
echo '<pre>',print_r($sorted_array),'</pre>';

最新更新