基于条件筛选排序对象数组:按RouteId去重并按AreaCode长度排序
解决方案
样本数据
const sampleData = [{ RouteId: "1", InDirection: "1", AreaCode: ["41108", "41109", "41110", "41111"], }, { RouteId: "1", InDirection: "2", AreaCode: ["41108", "41109", "411011"], }, { RouteId: "2", InDirection: "1", AreaCode: ["41112", "41114"], }, { RouteId: "2", InDirection: "2", AreaCode: ["41112", "41114"], }, { RouteId: "3", InDirection: "1", AreaCode: ["41112", "41114"], }, { RouteId: "3", InDirection: "2", AreaCode: ["41112", "41114","41108", "41109", "41110"], }, { RouteId: "4", InDirection: "1", AreaCode: ["41112", "41114","41108", "41110" , "41120", "41121"], }, { RouteId: "4", InDirection: "2", AreaCode: ["41112", "41114"], }]
需求回顾
- 每个
RouteId仅保留一个对象:- 同一
RouteId下有InDirection为1和2的两个对象时,保留AreaCode元素数量更多的 - 数量相等时任选其一
- 同一
- 最终结果按
AreaCode元素数量排序,取前20条
现有代码问题
- 未处理
AreaCode长度相等的场景,会导致同一RouteId的两个对象都被保留 - 未对结果做排序处理
完整解决方案代码
// 1. 按RouteId分组,每组保留AreaCode更长的对象;长度相等则保留先出现的 const groupedData = sampleData.reduce((acc, currentItem) => { const existingItem = acc[currentItem.RouteId]; if (!existingItem) { acc[currentItem.RouteId] = currentItem; } else { // 仅当当前项的AreaCode更长时,替换已有项 if (currentItem.AreaCode.length > existingItem.AreaCode.length) { acc[currentItem.RouteId] = currentItem; } } return acc; }, {}); // 2. 提取分组后的所有有效对象 const filteredList = Object.values(groupedData); // 3. 按AreaCode长度降序排序 const sortedList = filteredList.sort((a, b) => b.AreaCode.length - a.AreaCode.length); // 4. 取前20条结果 const finalResult = sortedList.slice(0, 20); console.log(finalResult);
代码说明
- 分组逻辑:用
reduce遍历数据,为每个RouteId维护最优对象,自动处理了长度相等的情况(保留先遍历到的对象,若想保留后出现的,把判断条件改成>=即可) - 排序逻辑:通过
sort方法按AreaCode长度降序排列,确保元素多的在前 - 截断逻辑:
slice(0,20)保证即使数据量超过20,也只取前20条
运行后得到的结果顺序为:
RouteId4(AreaCode长度6)→ RouteId3(长度5)→ RouteId1(长度4)→ RouteId2(长度2),完全符合需求。
内容的提问来源于stack exchange,提问作者Bonzo
相关产品推荐
相关产品推荐

