如何使用JavaScript修改数组中相同score对象的position属性为对应区间值
实现方案
因为原数组本身已经按score降序排列,相同score的元素是连续的,所以可以用双指针单次遍历完成,逻辑简洁性能更高:
- 用左指针标记当前同score分组的起始位置
- 向右找到当前分组的结束位置(和起始位置score相同的最后一个元素下标)
- 生成分组对应的position区间值:如果分组只有1个元素就直接用原position转字符串,多个就拼接为
起始position-结束position - 批量更新分组内所有元素的position属性
- 左指针跳到当前分组结束位置的下一位,重复上述步骤直到遍历完整个数组
可运行代码
function updatePosition(data) { let i = 0; const len = data.length; while (i < len) { // 找当前score相同分组的最右边界 let r = i; while (r + 1 < len && data[r + 1].score === data[i].score) { r++; } // 生成区间字符串 const posStr = i === r ? `${data[i].position}` : `${data[i].position}-${data[r].position}`; // 批量更新当前分组的position for (let k = i; k <= r; k++) { data[k].position = posStr; } // 跳到下一组的起始位置 i = r + 1; } return data; } // 调用测试 const data = [ { position: 1, name: "a", score: 9000 }, { position: 2, name: "b", score: 8000 }, { position: 3, name: "c", score: 6000 }, { position: 3, name: "c", score: 6000 }, { position: 4, name: "d", score: 6000 }, { position: 5, name: "e", score: 6000 }, { position: 6, name: "f", score: 6000 }, { position: 7, name: "g", score: 4000 }, { position: 8, name: "h", score: 3000 }, { position: 9, name: "i", score: 2500 }, { position: 10, name: "j", score: 2500 }, { position: 11, name: "k", score: 1000 }, { position: 12, name: "l", score: 1000 }, ]; updatePosition(data); console.log(data); // 输出结果和需求完全一致
原代码问题说明
你之前的实现用了多层嵌套循环,全局统计同score的元素数量,默认同score的元素都在当前i的后方连续排列,鲁棒性差,而且多余的repeat变量没有实际用到,容易出现索引越界或者区间计算错误的问题。上面的双指针方案时间复杂度为O(n),每个元素只会被访问两次,性能和可读性都更好。
内容的提问来源于stack exchange,提问作者Michal Podgorni
相关产品推荐
相关产品推荐

