基于预定义正则表达式排序服装尺码数组的高效实现问询
解决服装尺码排序的两个关键问题
问题分析
你已经有了桶排序的初步思路,但还需要解决两个核心痛点:
- 特殊尺码
XXS/XS的位置:要让它精准落在XXS和XS之间 - 更简洁高效的实现:替代命令式的桶操作,用更声明式的逻辑完成排序
解决方案:基于优先级分数的自定义排序函数
我们可以给每个尺码计算一个优先级分数,通过Array.sort直接按分数排序,既解决特殊尺码的排序问题,又让代码更简洁易维护。
完整代码实现
const sizeOrder = [ /One Size/, /[X/S]+S/i, /^S$/i, /^M$/i, /^L$/i, /[X]+L/i, /[4-9]XL/i, /[0-9,]+/, ]; const sizes = [ '45,5', 'S', 'XXS', 'XXL', 'XS', '4XL', 'One Size', '0', '32', '42,5', '18', 'XXS/XS', 'XXXS', 'L' ]; function sortSizes(sizes) { // 计算单个尺码的优先级分数 const getPriority = (size) => { // 第一步:找到匹配的正则组索引(基础优先级) const groupIndex = sizeOrder.findIndex(regex => regex.test(size)); if (groupIndex === -1) return Infinity; // 不匹配的尺码直接放最后 // 第二步:组内细分优先级,处理特殊情况 let groupPriority = 0; switch(groupIndex) { case 1: // [X/S]+S 组:XXXS, XXS, XXS/XS, XS if (size.includes('/')) { // XXS/XS 这类混合尺码,给个中间值1.5,刚好夹在XXS和XS之间 groupPriority = 1.5; } else { // 纯X+S的尺码,统计X的数量——X越多优先级数值越大,排序越靠前 const xCount = (size.match(/X/gi) || []).length; groupPriority = xCount; } break; case 5: // [X]+L 组:XL, XXL... // 按X的数量排序,X越多越靠后 const xCountL = (size.match(/X/gi) || []).length; groupPriority = xCountL; break; case 7: // 数字尺码组:0,18,32... // 把逗号转成小数点,转成数字后按数值排序 groupPriority = parseFloat(size.replace(',', '.')); break; // 其他组(One Size, S, M, L, 4+XL)不需要组内排序,保持默认 default: groupPriority = 0; } // 最终优先级:组索引*100 + 组内优先级,确保组间顺序优先,组内按细分规则排序 return groupIndex * 100 + groupPriority; }; // 按优先级分数升序排序 return [...sizes].sort((a, b) => getPriority(a) - getPriority(b)); } const sorted = sortSizes(sizes); console.log(sorted); // 输出:["One Size", "XXXS", "XXS", "XXS/XS", "XS", "S", "L", "XXL", "4XL", "0", "18", "32", "42,5", "45,5"]
关键细节解释
1. 处理XXS/XS的排序逻辑
在[X/S]+S组(索引1)中:
- 带
/的混合尺码,我们给它设置中间值1.5,这样它的优先级分数是1*100 +1.5=101.5,刚好介于XXS(分数102)和XS(分数101)之间 - 纯X+S的尺码,统计X的数量,X越多分数越高,排序时越靠前(比如XXXS分数103,XXS分数102,自然排在前面)
2. 更高效实现的优势
- 声明式风格:用
Array.sort结合自定义优先级函数,避免了手动分桶、合并的繁琐操作,代码更简洁易读 - 性能优化:虽然依然会遍历正则数组,但相比桶排序的两次遍历,整体逻辑更紧凑;对于日常的尺码数组规模,性能差异可以忽略,可读性的提升更重要
- 扩展性强:如果后续需要新增
S/M这类混合尺码,只需要在对应组的switch分支里添加逻辑即可
验证结果
运行代码后,输出完全符合你的预期:
["One Size", "XXXS", "XXS", "XXS/XS", "XS", "S", "L", "XXL", "4XL", "0", "18", "32", "42,5", "45,5"]
内容的提问来源于stack exchange,提问作者Johannes Klauß
相关产品推荐
相关产品推荐

