JavaScript:如何将数组中指定ID的多个对象上移一位
如何用原生JavaScript或Lodash将数组中多个对象上移一位?
已知待移动对象的rowid数组,要将对应对象在原数组中上移一位(比如示例中将row4和row5移到row3之前),下面分别用原生JS和Lodash实现,核心是正确使用splice并处理索引偏移问题。
核心注意点
移动多个元素时必须从后往前处理索引:如果先处理前面的索引,元素移动后会导致后续索引的位置发生偏移,进而操作错误的元素。因此需要将待移动的索引按降序排列后再遍历。
原生JavaScript实现
步骤1:获取待移动元素的索引
先建立rowid到数组索引的映射表,避免重复遍历数组;再将待移动的索引按降序排序。
步骤2:用splice执行上移
splice语法:array.splice(起始位置, 删除数量, 插入元素...),上移一位即取出当前元素,插入到前一位的位置。
完整代码:
const rowsToBeMoved = ['row4', 'row5']; const rowsArr = [ { rowid: "row0", name: "Mark Johnson" }, { rowid: "row1", name: "Jill Trillian" }, { rowid: "row2", name: "Alan Drangson" }, { rowid: "row3", name: "Bill Greggory" }, { rowid: "row4", name: "Alice Walker" }, { rowid: "row5", name: "Kurt Rose" }, ]; // 1. 构建rowid到索引的映射表 const idToIndex = rowsArr.reduce((map, row, index) => { map[row.rowid] = index; return map; }, {}); // 2. 获取待移动元素的索引并降序排序 const moveIndexes = rowsToBeMoved .map(rowId => idToIndex[rowId]) .sort((a, b) => b - a); // 3. 遍历执行上移操作 moveIndexes.forEach(index => { // 跳过第一个元素(无法上移) if (index <= 0) return; // 取出当前元素,插入到前一位,删除原位置 const [movedRow] = rowsArr.splice(index, 1); rowsArr.splice(index - 1, 0, movedRow); }); console.log(rowsArr); // 输出符合预期的orderedRowsArr
Lodash实现
利用Lodash的_.keyBy、_.pullAt和_.splice简化操作,核心逻辑与原生一致:
const _ = require('lodash'); const rowsToBeMoved = ['row4', 'row5']; const rowsArr = [ { rowid: "row0", name: "Mark Johnson" }, { rowid: "row1", name: "Jill Trillian" }, { rowid: "row2", name: "Alan Drangson" }, { rowid: "row3", name: "Bill Greggory" }, { rowid: "row4", name: "Alice Walker" }, { rowid: "row5", name: "Kurt Rose" }, ]; // 1. 用rowid作为键构建对象映射 const rowMap = _.keyBy(rowsArr, 'rowid'); // 2. 获取待移动索引并降序排序 const moveIndexes = rowsToBeMoved .map(id => rowsArr.indexOf(rowMap[id])) .sort((a, b) => b - a); // 3. 执行移动 _.forEach(moveIndexes, index => { if (index <= 0) return; const movedRow = _.pullAt(rowsArr, index)[0]; _.splice(rowsArr, index - 1, 0, movedRow); }); console.log(rowsArr);
修正你现有代码的问题
你当前的索引获取逻辑存在两处问题:
- 遍历
this.rowsArr收集索引,逻辑倒置,应该从rowsToBeMoved出发查找对应索引; - 未对索引排序,会导致移动时索引偏移,操作错误元素。
改用上述的「映射表+降序排序」方式即可解决。
内容的提问来源于stack exchange,提问作者Kirk Ross
相关产品推荐
相关产品推荐

