如何按指定规则优雅排序对象数组?现有实现求优化方案
优雅实现自定义规则的对象数组排序
需求说明
需要对包含Name属性的对象数组执行自定义排序,规则如下:
- 首元素为
Camel或Absolute(数组中存在哪个就取哪个,两者都存在时保留原数组中先出现的那个) - 第二个元素固定为
Dream - 第三个元素固定为
Carnival
示例1
输入:
[{ 'Name':'Carnival', 'TypeId':3 }, { 'Name':'Camel', 'TypeId':55 }, { 'Name':'Dream', 'TypeId':4 }]
输出:
[{ 'Name':'Camel', 'TypeId':55 }, { 'Name':'Dream', 'TypeId':4 }, { 'Name':'Carnival', 'TypeId':3 }]
示例2
输入:
[{ 'Name':'Carnival', 'TypeId':3 }, { 'Name':'Dream', 'TypeId':4 }, { 'Name':'Absolute', 'TypeId':114 }]
输出:
[{ 'Name':'Absolute', 'TypeId':114 }, { 'Name':'Dream', 'TypeId':4 }, { 'Name':'Carnival', 'TypeId':3 }]
现有实现的可优化点
你当前的实现逻辑可行,但存在冗余的条件判断(如循环中跳过索引1、多次filter调用),可以通过更直观的逻辑重构,提升代码可读性和简洁性。
优雅实现方案
方案一:直接构建结果数组(针对固定3元素场景)
这种方式逻辑直白,专为当前固定的排序规则设计,效率更高:
private _setUpdateProgress() { // 定义首元素的候选顺序,优先取Camel,找不到则取Absolute const firstCandidates = ['Camel', 'Absolute']; // 固定顺序的后续元素 const fixedOrder = ['Dream', 'Carnival']; if (!this.items?.length) { this.itemsSorted = []; return; } // 找到第一个符合条件的首元素 const firstItem = this.items.find(item => firstCandidates.includes(item.Name)); // 按固定顺序提取对应元素 const fixedItems = fixedOrder.map(name => this.items.find(item => item.Name === name)); // 组合结果并过滤可能的undefined(处理输入缺少元素的情况) this.itemsSorted = [firstItem, ...fixedItems].filter(Boolean); }
优势
- 逻辑清晰:把首元素候选和固定顺序元素分开定义,代码可读性拉满
- 减少冗余:避免循环内的条件跳转和重复过滤,用
find直接定位元素更高效 - 健壮性强:自动过滤不存在的元素,兼容输入数组缺少部分目标元素的场景
方案二:通用排序函数(适合扩展规则场景)
如果后续需要新增排序规则,或者数组包含更多其他元素,可以用自定义排序比较函数:
private _setUpdateProgress() { // 定义每个Name对应的排序优先级 const priorityMap = new Map([ ['Camel', 1], ['Absolute', 1], ['Dream', 2], ['Carnival', 3] ]); this.itemsSorted = this.items?.slice().sort((a, b) => { // 不在规则内的元素默认优先级为4,排到最后 const priorityA = priorityMap.get(a.Name) ?? 4; const priorityB = priorityMap.get(b.Name) ?? 4; // 优先级相同时(如Camel和Absolute),保留它们在原数组中的顺序 if (priorityA === priorityB) { return this.items.indexOf(a) - this.items.indexOf(b); } return priorityA - priorityB; }) || []; }
优势
- 扩展性好:新增排序规则只需在
priorityMap中添加键值对 - 保留原序:优先级相同的元素会维持在原数组中的出现顺序
- 兼容性广:自动处理不在规则内的元素,将其统一排到末尾
内容的提问来源于stack exchange,提问作者user7046311
相关产品推荐
相关产品推荐

