如何高效按指定ID数组顺序拆分JavaScript对象数组?
高效生成指定顺序的子数组方案
原始数据与需求
给定初始对象数组和两个ID数组:
const arr = [ { id: 1, name: "John" }, { id: 7, name: "Alice" }, { id: 10, name: "Ken" }, { id: 5, name: "Bob" }, { id: 2, name: "Kevin" }, { id: 6, name: "Tony" }, { id: 3, name: "Harry" }, { id: 4, name: "Kyle" }, { id: 8, name: "Jane" }, { id: 9, name: "Sam" }, ]; const list1 = [1, 4, 2]; const list2 = [3, 8, 9, 10];
需求:生成两个子数组subArr1和subArr2,分别包含arr中ID匹配list1、list2的对象,且子数组的对象顺序必须与对应ID数组的顺序完全一致。
原方案通过forEach+findIndex实现,但数据量大时,每次findIndex都会遍历整个arr,时间复杂度为O(mn)*(m是ID数组长度,n是arr长度),效率较低;而filter+includes的写法虽然简洁,但无法保证子数组顺序与ID数组一致。
优化方案:利用映射对象降低查找复杂度
核心思路是先将arr转换为以id为键、对应对象为值的映射(哈希表),这样查找单个ID对应的对象的时间复杂度降为O(1),之后遍历ID数组直接取值即可,既保证顺序,又将整体时间复杂度优化到O(n + m)(n是arr长度,m是所有ID数组的总长度)。
具体实现代码
// 第一步:创建ID到对象的映射 const idMap = arr.reduce((map, item) => { map[item.id] = item; return map; }, {}); // 第二步:生成对应子数组,同时过滤掉arr中不存在的ID,以及去重(如果ID数组有重复) const getSubArray = (idList) => { const seen = new Set(); return idList.reduce((result, id) => { if (idMap[id] && !seen.has(id)) { seen.add(id); result.push(idMap[id]); } return result; }, []); }; const subArr1 = getSubArray(list1); const subArr2 = getSubArray(list2);
代码说明
- 映射创建:使用
reduce遍历一次arr,构建idMap,后续查找对象无需再遍历原数组。 - 子数组生成:通过通用函数
getSubArray处理ID数组,用Set记录已添加的ID实现去重,同时判断idMap中是否存在该ID,避免添加不存在的对象。 - 顺序保证:遍历ID数组的顺序直接决定了子数组的元素顺序,完全符合需求。
运行结果
// subArr1 [ { id: 1, name: "John" }, { id: 4, name: "Kyle" }, { id: 2, name: "Kevin" } ] // subArr2 [ { id: 3, name: "Harry" }, { id: 8, name: "Jane" }, { id: 9, name: "Sam" }, { id: 10, name: "Ken" } ]
内容的提问来源于stack exchange,提问作者tuankiet0301
相关产品推荐
相关产品推荐

