如何将数组中的未匹配元素追加到排序后的数组末尾?
解决自定义排序并将未匹配元素移至末尾的问题
你的原代码存在一个关键问题:defaultOrder.indexOf(a.item)无法正确获取元素的排序索引,因为defaultOrder是对象数组,而a.item是字符串,indexOf会在数组里寻找完全匹配的字符串元素,结果永远返回-1,导致排序逻辑失效。
要实现自定义顺序排序,并将未匹配的元素(比如Duck)移至数组末尾,可以按以下步骤修改:
1. 创建顺序映射表
先把defaultOrder中的item值和对应的索引存储到一个Map中,这样后续查找排序索引的效率是O(1),比每次循环查找更高效:
const defaultOrder = [ {'item': 'Pen', 'value': '5'}, {'item': 'Spike', 'value': '5'}, {'item': 'Pencil', 'value': '5'}, {'item': 'Ink', 'value': '5'}, {'item': 'Mail', 'value': '5'}, {'item': 'Rubber', 'value': '5'} ]; // 构建item到排序索引的映射 const orderMap = new Map(); defaultOrder.forEach((entry, index) => { orderMap.set(entry.item, index); });
2. 修改排序逻辑
在排序函数中,处理三种情况:
- 两个元素都在自定义顺序中:按映射的索引差排序
- 其中一个元素不在自定义顺序中:将未匹配的元素移至后面
- 两个元素都不在自定义顺序中:可选按
item名称的字典序排序(也可以保持原顺序)
完整排序代码:
let items = [ {'item': 'Spike', 'value': '5'}, {'item': 'Duck', 'value': '5'}, {'item': 'Ink', 'value': '5'}, {'item': 'Pencil', 'value': '5'}, {'item': 'Rubber', 'value': '5'}, {'item': 'Mail', 'value': '5'}, {'item': 'Pen', 'value': '5'} ]; const orderedItems = items.sort((a, b) => { const aIdx = orderMap.get(a.item); const bIdx = orderMap.get(b.item); // 两个元素都在自定义顺序中,按索引排序 if (aIdx !== undefined && bIdx !== undefined) { return aIdx - bIdx; } // a不在自定义顺序,让它排后面 if (aIdx === undefined) { return 1; } // b不在自定义顺序,让它排后面 if (bIdx === undefined) { return -1; } // 两个都不在,按item名称字典序排序(可选,也可以返回0保持原顺序) return a.item.localeCompare(b.item); }); console.log(orderedItems);
运行后,orderedItems会按照Pen→Spike→Pencil→Ink→Mail→Rubber→Duck的顺序排列,未匹配的Duck被移至末尾。
内容的提问来源于stack exchange,提问作者Arnold Jr.
相关产品推荐
相关产品推荐

