刚刚参加了一次总结面试,面试官给我布置了一个涉及CRUD操作的任务。该任务具体需要显示按“display_order”列排序的数据。在表格列表中,有一个复选框允许用户重新排列顺序。为此,必须选中该框并指定显示顺序的起点。例如:
示例:
起点:2
原名单:
id | 显示顺序 | 复选框 |
---|---|---|
69 | 1 | |
71 | 2 | |
37 | 3 | |
52 | 4 | |
59 | 5 | |
60 | 6 | |
86 | 7 | 已检查 |
84 | 8 | |
77 | 9 | 已检查 |
44 | 10 | 已检查 |
预期结果:
id | 显示顺序 | 复选框 |
---|---|---|
69 | 1 | |
86 | 2 | |
77 | 3 | |
44 | 4 | |
71 | 5 | |
37 | 6 | |
52 | 7 | |
59 | 8 | |
60 | 9 | |
84 | 10 |
结果:
[
{
"id": "69",
"sort": 1
},
{
"id": "86",
"sort": "2"
},
{
"id": "77",
"sort": "3"
},
{
"id": "44",
"sort": "4"
},
{
"id": "52",
"sort": 5
},
{
"id": "71",
"sort": 5
},
{
"id": "37",
"sort": 5
},
{
"id": "59",
"sort": "5"
},
{
"id": "60",
"sort": "6"
},
{
"id": "84",
"sort": "8"
}
]
另一个例子: 起点:8
预期结果:
id | 显示顺序 | 复选框 |
---|---|---|
69 | 1 | |
71 | 2 | |
37 | 3 | |
52 | 4 | |
59 | 5 | |
60 | 6 | |
84 | 7 | |
86 | 8 | |
77 | 9 | |
44 | 10 |
结果:
[
{
"id": "69",
"sort": 1
},
{
"id": "71",
"sort": 2
},
{
"id": "37",
"sort": 3
},
{
"id": "52",
"sort": 4
},
{
"id": "59",
"sort": 5
},
{
"id": "60",
"sort": 6
},
{
"id": "86",
"sort": "8"
},
{
"id": "77",
"sort": "9"
},
{
"id": "44",
"sort": "10"
},
{
"id": "84",
"sort": 11
}
]
这是我到目前为止的代码:
public function reorder_list($request, $model = 'talk_news') {
$inputted_display_order = 7;
if (isset($request['sortable']) && $request['sortable']) {
$this->setOrm(ORM::for_table($model));
$sorted_ids = array_column($request['sortable'], 'id');
$sorted_display_order = array_column($request['sortable'], 'sort');
$first_display_order = reset($sorted_display_order);
$last_display_order = end($sorted_display_order);
$new_order = [];
$query = $this->_orm->select('id')
->select('display_order')
->where_not_in('id', $sorted_ids)
->order_by_asc('display_order')
->find_array();
$starting_display_order = $first_display_order == 1 ? count($sorted_display_order) + 1 : 1;
foreach($query as $item) {
$id = $item['id'];
$display_order = $item['display_order'];
$sort_value = $starting_display_order++;
if ($display_order > $last_display_order && $first_display_order != 1) {
$sort_value = $display_order;
}
if($display_order >= min($sorted_display_order) && $display_order <= max($sorted_display_order) && $first_display_order != 1) {
$count_to_max = (max($sorted_display_order) + 1) - $display_order;
$sort_value = $display_order + $count_to_max;
}
$new_order[] = [
'id' => $id,
'sort' => $sort_value
];
}
$new_order = array_merge($new_order, $request['sortable']);
usort($new_order, function ($a, $b) {
return $a['sort'] - $b['sort'];
});
return $new_order;
}
}
它通过了一些测试,但输入 2、8 以及大于最后选择的显示顺序(例如 11)时,它会打乱列表的顺序。
public function reorder_list($request, $model = 'talk_news') {
$inputted_display_order = 7;
if (isset($request['sortable']) && $request['sortable']) {
$this->setOrm(ORM::for_table($model));
$sorted_ids = array_column($request['sortable'], 'id');
$sorted_display_order = array_column($request['sortable'], 'sort');
$starting_display_order = max($sorted_display_order) + 1;
$remaining_items = $this->_orm
->select('id')
->select('display_order')
->where_not_in('id', $sorted_ids)
->order_by_asc('display_order')
->find_array();
$new_order = [];
foreach ($remaining_items as $item) {
if ($item['display_order'] < $inputted_display_order) {
$new_order[] = [
'id' => $item['id'],
'sort' => $item['display_order']
];
}
}
foreach ($request['sortable'] as $item) {
$new_order[] = [
'id' => $item['id'],
'sort' => $starting_display_order++
];
}
foreach ($remaining_items as $item) {
if ($item['display_order'] >= $inputted_display_order) {
$new_order[] = [
'id' => $item['id'],
'sort' => $starting_display_order++
];
}
}
usort($new_order, function ($a, $b) {
return $a['sort'] - $b['sort'];
});
return $new_order;
}
}