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

时间:2015-04-27 22:19:53

标签: php arrays

尝试按照它所属的顶级类别对比萨浇头的二维数组进行排序。但客户提供数据的方式并非理想。这是一个数据样本:

        [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被发送到梯级以进行进一步比较。想了解我做错了什么。谢谢。

2 个答案:

答案 0 :(得分:2)

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

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

答案 1 :(得分:2)

这是解决问题的一种方法。我刚刚把所有的浇头分成了自己的数组,然后在最后将它们合并在一起:

<?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>';