JavaScript数组优化:单遍历实现带前缀元素优先的排序需求
优化数组排序与分组的单次遍历实现
需求说明
处理后端返回的数组,将名称以TEST:为前缀的元素置于数组顶部,其余元素按名称字母顺序排序。现有实现通过两次filter分别筛选分组,希望改为单次遍历完成,同时提升代码可读性。
示例数组
const dataFromBE = [ {name: 'item one' , id: 1}, {name: 'item two' , id: 2}, {name: 'TEST:1' , id: 3}, {name: 'TEST:1' , id: 4}, {name: 'ASC item' , id: 5}, {name: 'some item' , id: 6}, {name: 'ASC item' , id: 6}, ];
现有实现(两次遍历)
const itemsWithPrefix = tags?.filter( (item) => item.name && item.name.toUpperCase().startsWith('TEST:') ); const otherItems = tags?.filter( (item) => item.name && !item.name.toUpperCase().startsWith('TEST:') ); let mergedArr: any[] = []; if (itemsWithPrefix && otherItems) { mergedArr = [...itemsWithPrefix, ...otherItems?.sort((a, b) => (a.name > b.name ? 1 : -1))]; }
优化后的单次遍历实现
// 定义类型,替代any提升类型安全 type BEItem = { name: string; id: number }; const processBEData = (data: BEItem[]) => { // 初始化两个分组容器,命名清晰 const testPrefixItems: BEItem[] = []; const regularItems: BEItem[] = []; // 单次遍历完成分组 for (const item of data) { // 处理name为空的边界情况 if (!item.name) { regularItems.push(item); continue; } // 统一转大写判断前缀,避免大小写敏感问题 const isTestItem = item.name.toUpperCase().startsWith('TEST:'); isTestItem ? testPrefixItems.push(item) : regularItems.push(item); } // 对普通元素按名称字母排序,使用localeCompare更严谨 regularItems.sort((a, b) => { if (!a.name) return 1; // 空name元素放末尾 if (!b.name) return -1; return a.name.localeCompare(b.name); }); // 合并分组,前缀元素在前 return [...testPrefixItems, ...regularItems]; }; // 调用示例 const processedData = processBEData(dataFromBE); console.log(processedData);
优化亮点
- 单次遍历:仅遍历数组一次完成分组,相比两次
filter减少了一次全量遍历,性能更优 - 可读性提升:用语义化变量名区分分组,逻辑连贯易理解
- 边界处理:考虑了
item.name为空的情况,避免运行时错误 - 排序严谨:使用
localeCompare替代手动字符串比较,支持多语言场景下的正确排序 - 类型安全:明确定义
BEItem类型,避免any类型带来的潜在问题
内容的提问来源于stack exchange,提问作者Cinovates
相关产品推荐
相关产品推荐

