如何使用JavaScript按自定义参考顺序重新排列对象数组
实现方案
通过优先级映射结合数组排序方法即可实现需求,该方案可同时覆盖参考数组为全量label、部分label两种场景。
核心逻辑
- 基于参考数组生成label到优先级的映射表,优先级数值越小排序越靠前
- 未出现在参考数组中的label优先级统一设为无穷大,保证排在匹配到的元素之后
- 优先级相同的元素保留原数组的相对顺序,满足部分匹配场景的需求
通用代码
const arr = [ {label: 'a', width: 200}, {label: 'b', width: 200}, {label: 'c', width: 200}, {label: 'd', width: 200}, {label: 'e', width: 200} ]; // 全量参考/部分参考都可以直接用这段代码 const data = ['d', 'e', 'a', 'c', 'b']; // const data = ['a', 'c']; // 生成优先级映射 const priorityMap = new Map(data.map((label, index) => [label, index])); // 排序(先解构复制避免修改原数组) const sortedArr = [...arr].sort((a, b) => { const priorityA = priorityMap.has(a.label) ? priorityMap.get(a.label) : Infinity; const priorityB = priorityMap.has(b.label) ? priorityMap.get(b.label) : Infinity; return priorityA - priorityB; });
兼容老旧环境写法
如果运行环境不支持ES2019+的稳定sort特性,可以通过额外记录原始索引的方式保证未匹配元素的相对顺序:
const sortedArr = arr.map((item, originIndex) => ({ ...item, originIndex })) .sort((a, b) => { const priorityA = priorityMap.has(a.label) ? priorityMap.get(a.label) : Infinity; const priorityB = priorityMap.has(b.label) ? priorityMap.get(b.label) : Infinity; if (priorityA !== priorityB) return priorityA - priorityB; // 优先级相同时按原始索引排序,保留原有相对顺序 return a.originIndex - b.originIndex; }) .map(({ originIndex, ...rest }) => rest);
效果验证
- 参考数组为
['d', 'e', 'a', 'c', 'b']时,输出数组的label顺序和参考数组完全一致 - 参考数组为
['a', 'c']时,输出数组的label顺序为a、c、b、d、e,符合补充要求
内容的提问来源于stack exchange,提问作者xoomer
相关产品推荐
相关产品推荐

