我有一组StdClass对象,包含不同的车型(例如紧凑型车,中型车等)。应按以下顺序对数组进行排序:
我遇到了按价格对剩余车辆进行分类的问题。我尝试先按价格排序,然后按第二次排序中的有序列表排序,但它没有按预期工作。任何帮助,将不胜感激。我之前发布了一个类似的问题,但我想我会重新发布一个更有条理的需求版本。
输入数组:
array (
0 =>
stdClass::__set_state(array(
'description' => 'Mid-Size SUV',
'codes' =>
array (
0 => 'IFAR',
),
'max_people' => '5',
'min_people' => '5',
'max_bags' => '4',
'min_bags' => '1',
'price' => '30.31',
)),
1 =>
stdClass::__set_state(array(
'description' => 'Standard-Size SUV',
'codes' =>
array (
0 => 'SFAR',
1 => 'RFAR',
),
'max_people' => '7',
'min_people' => '5',
'max_bags' => '4',
'min_bags' => '1',
'price' => '35.53',
)),
2 =>
stdClass::__set_state(array(
'description' => 'Economy Car',
'codes' =>
array (
0 => 'ECAR',
1 => 'EDAR',
),
'max_people' => '5',
'min_people' => '4',
'max_bags' => '2',
'min_bags' => '1',
'price' => '37.21',
)),
3 =>
stdClass::__set_state(array(
'description' => 'Specialty Vehicle',
'codes' =>
array (
0 => 'XXAR',
),
'max_people' => false,
'min_people' => false,
'max_bags' => '',
'min_bags' => '',
'price' => '36.72',
)),
4 =>
stdClass::__set_state(array(
'description' => 'Compact Car',
'codes' =>
array (
0 => 'CCAR',
1 => 'CDAR',
),
'max_people' => '5',
'min_people' => '4',
'max_bags' => '3',
'min_bags' => '1',
'price' => '37.21',
)),
5 =>
stdClass::__set_state(array(
'description' => 'Mid-Size Car',
'codes' =>
array (
0 => 'ICAR',
1 => 'IDAR',
),
'max_people' => '5',
'min_people' => '5',
'max_bags' => '4',
'min_bags' => '1',
'price' => '39.46',
)),
6 =>
stdClass::__set_state(array(
'description' => 'Standard-Size Car',
'codes' =>
array (
0 => 'SCAR',
1 => 'SDAR',
),
'max_people' => '5',
'min_people' => '5',
'max_bags' => '4',
'min_bags' => '1',
'price' => '41.77',
)),
7 =>
stdClass::__set_state(array(
'description' => 'Minivan',
'codes' =>
array (
0 => 'MVAR',
),
'max_people' => '7',
'min_people' => '7',
'max_bags' => '5',
'min_bags' => '2',
'price' => '43.18',
)),
8 =>
stdClass::__set_state(array(
'description' => 'Full-Size Car',
'codes' =>
array (
0 => 'FCAR',
1 => 'FDAR',
),
'max_people' => '5',
'min_people' => '5',
'max_bags' => '4',
'min_bags' => '1',
'price' => '43.50',
)),
9 =>
stdClass::__set_state(array(
'description' => 'Compact SUV',
'codes' =>
array (
0 => 'CFAR',
),
'max_people' => '5',
'min_people' => '5',
'max_bags' => '3',
'min_bags' => '3',
'price' => '46.42',
)),
10 =>
stdClass::__set_state(array(
'description' => 'Full-Size Hybrid',
'codes' =>
array (
0 => 'FCAH',
),
'max_people' => false,
'min_people' => false,
'max_bags' => '',
'min_bags' => '',
'price' => '48.00',
)),
11 =>
stdClass::__set_state(array(
'description' => 'Standard-Size Convertible',
'codes' =>
array (
0 => 'STAR',
),
'max_people' => '4',
'min_people' => '4',
'max_bags' => '4',
'min_bags' => '1',
'price' => '48.39',
)),
12 =>
stdClass::__set_state(array(
'description' => 'Premium Car',
'codes' =>
array (
0 => 'PCAR',
),
'max_people' => '5',
'min_people' => '5',
'max_bags' => '4',
'min_bags' => '2',
'price' => '48.72',
)),
13 =>
stdClass::__set_state(array(
'description' => 'Sports Car',
'codes' =>
array (
0 => 'XSAR',
1 => 'SSAR',
),
'max_people' => '5',
'min_people' => '4',
'max_bags' => '3',
'min_bags' => '1',
'price' => '48.72',
)),
14 =>
stdClass::__set_state(array(
'description' => 'Luxury Car',
'codes' =>
array (
0 => 'LCAR',
1 => 'LDAR',
),
'max_people' => '5',
'min_people' => '5',
'max_bags' => '5',
'min_bags' => '1',
'price' => '52.16',
)),
15 =>
stdClass::__set_state(array(
'description' => 'Full-Size SUV',
'codes' =>
array (
0 => 'FFAR',
),
'max_people' => '8',
'min_people' => '7',
'max_bags' => '4',
'min_bags' => '2',
'price' => '52.92',
)),
16 =>
stdClass::__set_state(array(
'description' => 'Compact Convertible',
'codes' =>
array (
0 => 'CTAR',
),
'max_people' => '4',
'min_people' => '4',
'max_bags' => '1',
'min_bags' => '1',
'price' => '91.17',
)),
17 =>
stdClass::__set_state(array(
'description' => 'Premium SUV',
'codes' =>
array (
0 => 'PFAR',
1 => 'UFAR',
),
'max_people' => '7',
'min_people' => '5',
'max_bags' => '5',
'min_bags' => '1',
'price' => '92.64',
)),
18 =>
stdClass::__set_state(array(
'description' => 'Specialty Car',
'codes' =>
array (
0 => 'XCAR',
),
'max_people' => '5',
'min_people' => '5',
'max_bags' => '3',
'min_bags' => '3',
'price' => '94.42',
)),
19 =>
stdClass::__set_state(array(
'description' => 'Mid-Size Convertible',
'codes' =>
array (
0 => 'ITAR',
),
'max_people' => '4',
'min_people' => '4',
'max_bags' => '2',
'min_bags' => '2',
'price' => '97.98',
)),
20 =>
stdClass::__set_state(array(
'description' => 'Full-Size Van',
'codes' =>
array (
0 => 'FVAR',
),
'max_people' => '15',
'min_people' => '12',
'max_bags' => '5',
'min_bags' => '1',
'price' => '90.38',
)),
21 =>
stdClass::__set_state(array(
'description' => 'Luxury SUV',
'codes' =>
array (
0 => 'LFAR',
),
'max_people' => '5',
'min_people' => '5',
'max_bags' => '3',
'min_bags' => '3',
'price' => '113.66',
)),
22 =>
stdClass::__set_state(array(
'description' => 'Premium Convertible',
'codes' =>
array (
0 => 'PTAR',
),
'max_people' => '4',
'min_people' => '4',
'max_bags' => '1',
'min_bags' => '1',
'price' => '121.15',
)),
23 =>
stdClass::__set_state(array(
'description' => 'Luxury Convertible',
'codes' =>
array (
0 => 'LTAR',
),
'max_people' => '4',
'min_people' => '4',
'max_bags' => '1',
'min_bags' => '1',
'price' => '129.01',
)),
24 =>
stdClass::__set_state(array(
'description' => 'Premium Van',
'codes' =>
array (
0 => 'PVAR',
),
'max_people' => '15',
'min_people' => '15',
'max_bags' => '1',
'min_bags' => '1',
'price' => '159.49',
)),
25 =>
stdClass::__set_state(array(
'description' => 'Specialty Convertible',
'codes' =>
array (
0 => 'XTAR',
),
'max_people' => '4',
'min_people' => '4',
'max_bags' => '2',
'min_bags' => '2',
'price' => '307.64',
)),
)
代码:
$order = [
'Economy Car' => 1,
'Compact Car' => 2,
'Mid-Size Car' => 3,
'Standard-Size Car' => 4,
'Full-Size Car' => 5,
'Premium Car' => 6,
'Luxury Car' => 7,
'Standard-Size Convertible' => 8,
'Mid-Size SUV' => 9,
'Standard SUV' => 10,
'Full-Size SUV' => 11,
'Minivan' => 12
];
usort($car_types,function($a, $b) {
return $a->price == $b->price ? 0 : $a->price > $b->price;
});
usort($car_types, function($a, $b) use ($order) {
$a_set = intval(isset($order[$a->description]));
$b_set = intval(isset($order[$b->description]));
return $a_set === $b_set && $a_set === 1
? $order[$a->description] - $order[$b->description]
: $b_set - $a_set;
});
新输出:
Array
(
[0] => stdClass Object
(
[description] => Economy Car
[codes] => Array
(
[0] => ECAR
[1] => EDAR
)
[max_people] => 5
[min_people] => 4
[max_bags] => 2
[min_bags] => 1
[price] => 37.21
)
[1] => stdClass Object
(
[description] => Compact Car
[codes] => Array
(
[0] => CCAR
[1] => CDAR
)
[max_people] => 5
[min_people] => 4
[max_bags] => 3
[min_bags] => 1
[price] => 37.21
)
[2] => stdClass Object
(
[description] => Mid-Size Car
[codes] => Array
(
[0] => ICAR
[1] => IDAR
)
[max_people] => 5
[min_people] => 5
[max_bags] => 4
[min_bags] => 1
[price] => 39.46
)
[3] => stdClass Object
(
[description] => Standard-Size Car
[codes] => Array
(
[0] => SCAR
[1] => SDAR
)
[max_people] => 5
[min_people] => 5
[max_bags] => 4
[min_bags] => 1
[price] => 41.77
)
[4] => stdClass Object
(
[description] => Full-Size Car
[codes] => Array
(
[0] => FCAR
[1] => FDAR
)
[max_people] => 5
[min_people] => 5
[max_bags] => 4
[min_bags] => 1
[price] => 43.50
)
[5] => stdClass Object
(
[description] => Premium Car
[codes] => Array
(
[0] => PCAR
)
[max_people] => 5
[min_people] => 5
[max_bags] => 4
[min_bags] => 2
[price] => 48.72
)
[6] => stdClass Object
(
[description] => Luxury Car
[codes] => Array
(
[0] => LCAR
[1] => LDAR
)
[max_people] => 5
[min_people] => 5
[max_bags] => 5
[min_bags] => 1
[price] => 52.16
)
[7] => stdClass Object
(
[description] => Standard-Size Convertible
[codes] => Array
(
[0] => STAR
)
[max_people] => 4
[min_people] => 4
[max_bags] => 4
[min_bags] => 1
[price] => 48.39
)
[8] => stdClass Object
(
[description] => Mid-Size SUV
[codes] => Array
(
[0] => IFAR
)
[max_people] => 5
[min_people] => 5
[max_bags] => 4
[min_bags] => 1
[price] => 30.31
)
[9] => stdClass Object
(
[description] => Standard-Size SUV
[codes] => Array
(
[0] => SFAR
[1] => RFAR
)
[max_people] => 7
[min_people] => 5
[max_bags] => 4
[min_bags] => 1
[price] => 35.53
)
[10] => stdClass Object
(
[description] => Full-Size SUV
[codes] => Array
(
[0] => FFAR
)
[max_people] => 8
[min_people] => 7
[max_bags] => 4
[min_bags] => 2
[price] => 52.92
)
[11] => stdClass Object
(
[description] => Minivan
[codes] => Array
(
[0] => MVAR
)
[max_people] => 7
[min_people] => 7
[max_bags] => 5
[min_bags] => 2
[price] => 43.18
)
[12] => stdClass Object
(
[description] => Specialty Vehicle
[codes] => Array
(
[0] => XXAR
)
[max_people] =>
[min_people] =>
[max_bags] =>
[min_bags] =>
[price] => 36.72
)
[13] => stdClass Object
(
[description] => Compact SUV
[codes] => Array
(
[0] => CFAR
)
[max_people] => 5
[min_people] => 5
[max_bags] => 3
[min_bags] => 3
[price] => 46.42
)
[14] => stdClass Object
(
[description] => Sports Car
[codes] => Array
(
[0] => XSAR
[1] => SSAR
)
[max_people] => 5
[min_people] => 4
[max_bags] => 3
[min_bags] => 1
[price] => 48.72
)
[15] => stdClass Object
(
[description] => Full-Size Hybrid
[codes] => Array
(
[0] => FCAH
)
[max_people] =>
[min_people] =>
[max_bags] =>
[min_bags] =>
[price] => 48.00
)
[16] => stdClass Object
(
[description] => Full-Size Van
[codes] => Array
(
[0] => FVAR
)
[max_people] => 15
[min_people] => 12
[max_bags] => 5
[min_bags] => 1
[price] => 90.38
)
[17] => stdClass Object
(
[description] => Compact Convertible
[codes] => Array
(
[0] => CTAR
)
[max_people] => 4
[min_people] => 4
[max_bags] => 1
[min_bags] => 1
[price] => 91.17
)
[18] => stdClass Object
(
[description] => Premium SUV
[codes] => Array
(
[0] => PFAR
[1] => UFAR
)
[max_people] => 7
[min_people] => 5
[max_bags] => 5
[min_bags] => 1
[price] => 92.64
)
[19] => stdClass Object
(
[description] => Specialty Car
[codes] => Array
(
[0] => XCAR
)
[max_people] => 5
[min_people] => 5
[max_bags] => 3
[min_bags] => 3
[price] => 94.42
)
[20] => stdClass Object
(
[description] => Mid-Size Convertible
[codes] => Array
(
[0] => ITAR
)
[max_people] => 4
[min_people] => 4
[max_bags] => 2
[min_bags] => 2
[price] => 97.98
)
[21] => stdClass Object
(
[description] => Luxury SUV
[codes] => Array
(
[0] => LFAR
)
[max_people] => 5
[min_people] => 5
[max_bags] => 3
[min_bags] => 3
[price] => 113.66
)
[22] => stdClass Object
(
[description] => Premium Convertible
[codes] => Array
(
[0] => PTAR
)
[max_people] => 4
[min_people] => 4
[max_bags] => 1
[min_bags] => 1
[price] => 121.15
)
[23] => stdClass Object
(
[description] => Luxury Convertible
[codes] => Array
(
[0] => LTAR
)
[max_people] => 4
[min_people] => 4
[max_bags] => 1
[min_bags] => 1
[price] => 129.01
)
[24] => stdClass Object
(
[description] => Premium Van
[codes] => Array
(
[0] => PVAR
)
[max_people] => 15
[min_people] => 15
[max_bags] => 1
[min_bags] => 1
[price] => 159.49
)
[25] => stdClass Object
(
[description] => Specialty Convertible
[codes] => Array
(
[0] => XTAR
)
[max_people] => 4
[min_people] => 4
[max_bags] => 2
[min_bags] => 2
[price] => 307.64
)
)
答案 0 :(得分:1)
您可以通过拨打usort
来完成此操作。
首先,您还可以使用array_flip
来更轻松地管理$order
数组。这样您就不必输入(或更改)数字值:
$order = array_flip([
'Economy Car',
'Compact Car',
'Mid-Size Car',
'Standard-Size Car',
'Full-Size Car',
'Premium Car',
'Luxury Car',
'Standard-Size Convertible',
'Mid-Size SUV',
'Standard SUV',
'Full-Size SUV',
'Minivan'
]);
排序本身:
usort($car_types, function($a, $b) use ($order) {
$ret = (isset($order[$a->description]) ? $order[$a->description] : count($order))
- (isset($order[$b->description]) ? $order[$b->description] : count($order));
return $ret ? $ret : ($a->price - $b->price) * 100;
});
第一个作业根据 description 字段按顺序计算差异。如果未知订单,则取代默认值count($order)
(使用三元运算符):这样,在任何具有“{1}”数组的车型之后,将排序不在$order
数组中的汽车类型$order
中的条目。 count
函数在这里工作,假设您已经编号从0开始的类型(array_flip
的情况),但您可以使用任何足够多的数字。
return
语句然后检查上面的值是否与零不同,如果是,则返回它。如果为零,则返回价格差异(以美分计)。以美分为单位的值是因为返回值预期是整数,而不是浮点数。如documentation中所述:
警告:从比较函数返回非整数值,例如float,将导致内部强制转换为回调值的整数值。因此,诸如0.99和0.1之类的值都将被转换为0的整数值,这将将这些值比较为相等。
答案 1 :(得分:0)
因此,只需在$order
中分配 中的任何最大排序权重,然后在汽车具有相同权重时添加二级价格比较。这种方法要简单得多,只需要一个排序操作。
usort($car_types, function($a, $b) use ($order) {
$a_weight = key_exists($a->description, $order) ? $order[$a->description] : PHP_INT_MAX;
$b_weight = key_exists($b->description, $order) ? $order[$b->description] : PHP_INT_MAX;
if( $a_weight != $b_weight ) {
return $a_weight - $b_weight;
} else {
return ( $a->price - $b->price ) * 100;
}
});