Trying to sort an 2-dimensional array of pizza toppings by the category of topping it belongs to. But the way the client supplies the data isn't ideal for this. Here's a sample of the data:
试着按披萨配料所属的类别对二维的披萨配料进行排序。但是客户机提供数据的方式并不理想。以下是数据的样本:
[0] => Array
(
[id] => 30
[title] => Pepperoni
[meat] => 1
[veggie] =>
[sauce] =>
[cheese] =>
[condiment] =>
)
[1] => Array
(
[id] => 29
[title] => Onions
[meat] =>
[veggie] => 1
[sauce] =>
[cheese] =>
[condiment] =>
)
The idea is that the toppings should always be grouped by a type (ie. meat
) in a specific order (ie. meats
followed by veggies
followed by sauces
and so on)—independent of the order in which they're retrieved. Importantly, no topping ever belongs to two types.
其思想是,浇头应该总是按类型(ie)来分组。肉)按特定的顺序。肉类接着是蔬菜,然后是酱汁,等等)- - -独立于它们被回收的顺序。重要的是,任何浇头都不属于两种类型。
Here's my stab at this:
以下是我对此的尝试:
$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'];
}
);
This doesn't at all achieve my aims and I don't understand why; it seems to me that whenever $opt_a
has a higher score than $opt_b
it should keep it's position while $opt_b
gets sent down a rung for further comparisons. Would like to understand what I'm doing wrong. Thanks.
这根本不能实现我的目标,我也不明白为什么;在我看来,每当$opt_a的分数高于$opt_b时,它就应该保持它的位置,而$opt_b则会被降级以进行进一步的比较。我想知道我做错了什么。谢谢。
2 个解决方案
#1
2
- I think that your code is correct and problem in test data. Reorder them to see result
- 我认为您的代码是正确的,并且测试数据存在问题。重新排序以查看结果
-
To obtain correct result order, change code to
要获得正确的结果顺序,请将代码更改为
return $scores['b'] - $scores['a'];
返回分数[b]-几十美元[a];
#2
2
Here's one way to approach the situation. I've just separated all of the toppings into their own array and then merged them together at the end:
这里有一种处理这种情况的方法。我把所有的浇头都分解成它们自己的数组,最后把它们合并到一起:
<?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>';
#1
2
- I think that your code is correct and problem in test data. Reorder them to see result
- 我认为您的代码是正确的,并且测试数据存在问题。重新排序以查看结果
-
To obtain correct result order, change code to
要获得正确的结果顺序,请将代码更改为
return $scores['b'] - $scores['a'];
返回分数[b]-几十美元[a];
#2
2
Here's one way to approach the situation. I've just separated all of the toppings into their own array and then merged them together at the end:
这里有一种处理这种情况的方法。我把所有的浇头都分解成它们自己的数组,最后把它们合并到一起:
<?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>';