如何基于priority属性处理对象数组的优先级冲突与排序?
解决方案
要实现符合要求的优先级调整逻辑,核心是处理优先级冲突的连锁调整,同时尊重原数组中的优先级间隔(遇到间隔时停止连锁调整)。以下是具体实现步骤和代码:
核心逻辑梳理
当用户修改某行的优先级为newP时:
- 先将目标行的优先级临时设为
newP(此时可能存在冲突)。 - 从
newP开始向上检查:- 若当前优先级存在多行冲突,将冲突行(除目标行)的优先级+1。
- 检查原数组中是否同时存在当前优先级和下一个优先级(即是否连续无间隔):若存在间隔,停止调整;否则继续处理下一个优先级的冲突。
- 最终按优先级降序排序,保证显示顺序符合“数值越大重要性越高”的要求。
完整代码实现
1. 优先级调整工具函数
// 获取原数组的优先级集合(去重,排除当前编辑行) function getOriginalPrioritySet(rows, excludeRowId) { return new Set(rows.filter(r => r.id !== excludeRowId).map(r => r.priority)); } // 处理优先级冲突的核心函数 function adjustPriorityConflicts(originalRows, targetRowId, newPriority) { // 深拷贝数组,避免直接修改React状态 const rows = JSON.parse(JSON.stringify(originalRows)); const targetRow = rows.find(r => r.id === targetRowId); if (!targetRow) return rows; // 临时设置目标行的新优先级 targetRow.priority = newPriority; // 获取原数组的优先级集合(排除目标行) const originalPriorities = getOriginalPrioritySet(originalRows, targetRowId); let currentPriority = newPriority; while (true) { // 找到当前优先级的所有冲突行 const conflictRows = rows.filter(r => r.priority === currentPriority); if (conflictRows.length <= 1) { // 无冲突,退出循环 break; } // 调整冲突行(排除目标行)的优先级 const rowsToAdjust = conflictRows.filter(r => r.id !== targetRowId); rowsToAdjust.forEach(r => { r.priority = currentPriority + 1; }); // 检查原数组中是否存在连续的当前优先级和下一个优先级(无间隔) const hasCurrent = originalPriorities.has(currentPriority); const hasNext = originalPriorities.has(currentPriority + 1); if (!hasCurrent || !hasNext) { // 存在间隔,停止连锁调整 break; } currentPriority += 1; } // 按优先级降序排序 rows.sort((a, b) => b.priority - a.priority); return rows; }
2. 修改cellEdit配置
替换你原来的beforeSaveCell和afterSaveCell逻辑:
const cellEdit = { mode: 'click', beforeSaveCell: (oldValue, newValue, row, column) => { // 仅处理优先级列的编辑 if (column.dataField !== 'prioridade') return true; const newP = parseInt(newValue); if (isNaN(newP)) { // 无效数值,拒绝保存 return false; } // 处理优先级冲突,生成新的数组 const updatedRows = adjustPriorityConflicts(stateLinhas, row.id, newP); // 更新React状态 setStateLinhas(updatedRows); return true; }, // 无需再在afterSave中排序,状态更新后表格会自动重新渲染 afterSaveCell: () => {} };
3. 保持表格组件不变
你的BootstrapTable组件代码无需修改,确保data属性绑定stateLinhas即可。
关键细节说明
- 深拷贝数组:React状态是不可变的,必须创建新数组避免直接修改原状态。
- 间隔判断:通过原数组的优先级集合判断是否存在间隔,避免不必要的连锁调整。
- 排序逻辑:最终按优先级降序排序,保证表格显示顺序符合业务要求。
内容的提问来源于stack exchange,提问作者PeterO
相关产品推荐
相关产品推荐

