我从这样的数据库数组中获取(用户选择按价格排序):
Array
(
[0] => Array
(
[id] => 812
[price] => 0
[par_id] => 310
)
[1] => Array
(
[id] => 445
[price] => 3400
[par_id] => 0
)
[2] => Array
(
[id] => 1102
[price] => 3500
[par_id] => 0
)
[3] => Array
(
[id] => 310
[price] => 3700
[par_id] => 0
)
[4] => Array
(
[id] => 311
[price] => 3700
[par_id] => 310
)
[5] => Array
(
[id] => 800
[price] => 3900
[par_id] => 310
)
)
我需要将此数组排序为 par_id == 0 的项目,并在其下面显示其子项 child.par_id = parent.id 。要使用这些contidions获取数组,我使用函数usort():
usort($ array,“cmp ”);
function cmp($a, $b) {
if ( $a['id'] == $b['id'] ) {
return 0;
} else if ( $a['par_id'] ) {
if ( $a['par_id'] == $b['par_id'] ) {
return ( $a['id'] < $b['id'] ? -1 : 1 );
} else {
return ( $a['par_id'] >= $b['id'] ? 1 : -1 );
}
} else if ( $b['par_id'] ) {
return ( $b['par_id'] >= $a['id'] ? -1 : 1);
} else {
return ( $a['id'] < $b['id'] ? -1 : 1 );
}
}
它有效,然后我得到这样的数组:
Array
(
[0] => Array
(
[id] => 310
[price] => 3700
[par_id] => 0
)
[1] => Array
(
[id] => 311
[price] => 3700
[par_id] => 310
)
[2] => Array
(
[id] => 800
[price] => 3900
[par_id] => 310
)
[3] => Array
(
[id] => 812
[price] => 0
[par_id] => 310
)
[4] => Array
(
[id] => 445
[price] => 3400
[par_id] => 0
)
[5] => Array
(
[id] => 1102
[price] => 3500
[par_id] => 0
)
)
但是,这个数组没有按价格排序。我的问题是,如果可以在上面的状态中对数组进行排序,还要按价格进行排序,至少在父级(在孩子的理想情况下)也是如此。所以我想得到的结果数组是这样的:
Array
(
[0] => Array
(
[id] => 445
[price] => 3400
[par_id] => 0
)
[1] => Array
(
[id] => 1102
[price] => 3500
[par_id] => 0
)
[2] => Array
(
[id] => 310
[price] => 3700
[par_id] => 0
)
[3] => Array
(
[id] => 812
[price] => 0
[par_id] => 310
)
[4] => Array
(
[id] => 311
[price] => 3700
[par_id] => 310
)
[5] => Array
(
[id] => 800
[price] => 3900
[par_id] => 310
)
)
父母首先,紧接着他们的孩子并且仍按用户选择的价格排序。
答案 0 :(得分:1)
好问题。您没有比较cmp
函数中的价格,因此结果列表未按价格排序是合乎逻辑的。请查看以下cmp
函数:
function cmp($a, $b) {
if ($a['id'] === $b['id']) {
return 0;
}
// both are child or both are parents, so compare by price
$comparePrices = ($a['par_id'] && $b['par_id'])
|| (!$a['par_id'] && !$b['par_id']);
$priceResult = $a['price'] > $b['price'] ? 1 : -1;
if ($comparePrices) {
return $priceResult;
} else if ($a['par_id']) {
// a is a child, so check if b is the parent
return $a['par_id'] === $b['id'] ? 1 : $priceResult;
} else if ($b['par_id']) {
// b is a child, so check if a is the parent
return $b['par_id'] === $a['id'] ? -1 : $priceResult;
}
}
这应该有效,但不能保证它适用于所有情况。
为了便于阅读,您应该实现这一点。将您的查询拆分为两个。第一个按价格提取所有父母和订单,第二个按父母ID然后按价格提取所有孩子和订单。这些数组的合并操作是foreach
和array_map
的简单组合。例如:
$childItemsByParentId = [];
foreach ($childItems as $childItem) {
$childItemsByParentId[$childItem['par_id']][] = $childItem;
}
$parentItems = array_map(function ($parentItem) use ($childItemsByParentId) {
$childs = isset($childItemsByParentId[$parentItem['id']])
? $childItemsByParentId[$parentItem['id']]
: [];
$parentItem['childs'] = $childs;
return $parentItem;
}, $parentItems);
答案 1 :(得分:0)
我发明了另一种方法,最终如何做到这一点。
它遍历整个数组并查明实际项目是父项还是子项。如果是孩子,它会再次通过数组来查找其父级。如果父项被查找,它会向前或向后移动子项和父项之间的所有项(取决于子项的位置 - 如果在父项之前或之后)在数组中创建一个空格,将放置子项。
$last_id = 0;
for($i = 0; $i < count($data); $i++) {
$item = $data[$i];
if ($item['par_id'] == 0) {
$last_id = $item['id'];
continue;
}
if ($last_id == $item['par_id']) {
continue;
}
foreach($data as $d => $dat) {
if ($item['par_id'] == $dat['id']) {
if ($i < $d) {
for($j = $i; $j < $d; $j++) { $data[$j] = $data[$j + 1]; }
$empty = $d;
$i -= 1;
} else {
for($j = $i; $j > $d; $j--) { $data[$j] = $data[$j - 1]; }
$empty = $d + 1;
}
$data = $item;
} } }