Just attended a concluding interview where the interviewer assigned me a task involving CRUD operations. The task specifically entails displaying data sorted by the "display_order" column. Within the table list, there is a checkbox that allows users to rearrange the order. To do so, one must check the box and specify a starting point for the display order. For instance:
Example:
Starting point: 2
Original List:
id | display order | checkbox |
---|---|---|
69 | 1 | |
71 | 2 | |
37 | 3 | |
52 | 4 | |
59 | 5 | |
60 | 6 | |
86 | 7 | checked |
84 | 8 | |
77 | 9 | checked |
44 | 10 | checked |
Expected Result:
id | display order | checkbox |
---|---|---|
69 | 1 | |
86 | 2 | |
77 | 3 | |
44 | 4 | |
71 | 5 | |
37 | 6 | |
52 | 7 | |
59 | 8 | |
60 | 9 | |
84 | 10 |
The Result:
[
{
"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"
}
]
Another Example:
Starting point: 8
Expected Result:
id | display order | checkbox |
---|---|---|
69 | 1 | |
71 | 2 | |
37 | 3 | |
52 | 4 | |
59 | 5 | |
60 | 6 | |
84 | 7 | |
86 | 8 | |
77 | 9 | |
44 | 10 |
The Result:
[
{
"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
}
]
Here’s what I have so far for the code:
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;
}
}
To replicate this, I’ll provide the data from the query and for the $request[‘sortable’]:
Sample Data for $query:
[{"id":"69","display_order":"1"},{"id":"71","display_order":"2"},{"id":"37","display_order":"3"},{"id":"52","display_order":"4"},{"id":"59","display_order":"5"},{"id":"60","display_order":"6"},{"id":"84","display_order":"8"},{"id":"74","display_order":"11"},{"id":"64","display_order":"12"},{"id":"25","display_order":"13"},{"id":"70","display_order":"14"},{"id":"73","display_order":"15"},{"id":"68","display_order":"16"},{"id":"38","display_order":"17"},{"id":"26","display_order":"18"},{"id":"5","display_order":"19"},{"id":"33","display_order":"20"},{"id":"41","display_order":"21"},{"id":"40","display_order":"22"},{"id":"55","display_order":"23"},{"id":"57","display_order":"24"},{"id":"61","display_order":"25"},{"id":"65","display_order":"26"},{"id":"66","display_order":"27"},{"id":"67","display_order":"28"},{"id":"46","display_order":"29"},{"id":"76","display_order":"30"},{"id":"78","display_order":"31"},{"id":"79","display_order":"32"},{"id":"81","display_order":"33"}]
Sample data for $request[‘sortable’]
[{"id":"86","sort":"2"},{"id":"77","sort":"3"},{"id":"44","sort":"4"}]
2
Answers
You could re-index
$request['sortable']
so that you have an array ofid
s indexed bysort
. Then, for each display order take the id from the re-indexed array if it exists, elsearray_shift()
next item from beginning of$query
.Something like: