PHP:使用所选行和输入的起始点值重新排序显示顺序

问题描述 投票:0回答:1

刚刚参加了一次总结面试,面试官给我布置了一个涉及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)时,它会打乱列表的顺序。

php mysql arrays sorting data-structures
1个回答
-1
投票
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;
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.