/** * 歌曲排序功能验证脚本 * 运行方式: node verify_sort.js */ // 智能排序函数(与实际代码完全相同) function smartSort(titleA, titleB) { // 辅助函数:判断字符类型 const getCharType = (char) => { if (!char) return 3; // 空字符串排在最后 const code = char.charCodeAt(0); // 数字 (0-9) if (code >= 48 && code <= 57) return 0; // 英文字母 (A-Z, a-z) if ((code >= 65 && code <= 90) || (code >= 97 && code <= 122)) return 1; // 其他所有字符(符号、中文、日文等) return 2; }; // 辅助函数:提取首字符并确定类型 const getFirstCharInfo = (title) => { if (!title || title.length === 0) return { type: 3, char: '', title: '' }; const firstChar = title.charAt(0); const type = getCharType(firstChar); return { type, char: firstChar, title }; }; const infoA = getFirstCharInfo(titleA); const infoB = getFirstCharInfo(titleB); // 首先按字符类型排序:数字 < 字母 < 其他符号 if (infoA.type !== infoB.type) { return infoA.type - infoB.type; } // 同类型字符,使用 localeCompare 进行自然排序 return titleA.localeCompare(titleB, undefined, { numeric: true, sensitivity: 'base' }); } // 测试数据 const testSongs = [ "太鼓の達人", "Zyxwv Test", "123 Song", "abc melody", "456 rhythm", "*Special*", "10 drums", "あいうえお", "2 beats", "ZZZ Final", "1st Place", "100 percent", "ドンだー!", "Battle No.1", "~奇跡~", "777", "Angel Beats", "カノン", "Don't Stop", "零 -ZERO-", "3pieces", "Apple", "燎原ノ舞", "99 Balloons", "Brave Heart", "夏祭り", "5 Elements", "50音", "Zephyr", "α wave" ]; // 获取字符类型标签 function getTypeLabel(title) { const firstChar = title.charAt(0); const code = firstChar.charCodeAt(0); if (code >= 48 && code <= 57) return '[数字]'; if ((code >= 65 && code <= 90) || (code >= 97 && code <= 122)) return '[字母]'; return '[其他]'; } // 执行排序测试 console.log('\n' + '='.repeat(60)); console.log('🥁 Taiko Web - 歌曲智能排序功能测试'); console.log('='.repeat(60) + '\n'); console.log('📋 原始歌曲列表 (共 ' + testSongs.length + ' 首):'); console.log('-'.repeat(60)); testSongs.forEach((song, index) => { console.log(`${(index + 1).toString().padStart(2, ' ')}. ${song}`); }); console.log('\n' + '='.repeat(60)); console.log('⚙️ 执行智能排序...\n'); // 排序 const sortedSongs = [...testSongs].sort(smartSort); console.log('✅ 排序后的歌曲列表:'); console.log('-'.repeat(60)); let currentType = null; sortedSongs.forEach((song, index) => { const typeLabel = getTypeLabel(song); // 检测类型变化,添加分隔符 if (currentType !== typeLabel) { if (currentType !== null) { console.log(''); // 空行分隔不同类型 } currentType = typeLabel; } console.log(`${(index + 1).toString().padStart(2, ' ')}. ${song.padEnd(25, ' ')} ${typeLabel}`); }); console.log('\n' + '='.repeat(60)); console.log('📊 统计信息:'); console.log('-'.repeat(60)); // 统计各类型数量 let numberCount = 0; let letterCount = 0; let otherCount = 0; sortedSongs.forEach(song => { const label = getTypeLabel(song); if (label === '[数字]') numberCount++; else if (label === '[字母]') letterCount++; else otherCount++; }); console.log(`数字开头: ${numberCount} 首`); console.log(`字母开头: ${letterCount} 首`); console.log(`其他开头: ${otherCount} 首`); console.log(`总计: ${sortedSongs.length} 首`); console.log('\n' + '='.repeat(60)); console.log('✨ 排序规则验证:'); console.log('-'.repeat(60)); // 验证排序是否正确 let isValid = true; let prevType = -1; for (let i = 0; i < sortedSongs.length; i++) { const song = sortedSongs[i]; const firstChar = song.charAt(0); const code = firstChar.charCodeAt(0); let currentType; if (code >= 48 && code <= 57) currentType = 0; else if ((code >= 65 && code <= 90) || (code >= 97 && code <= 122)) currentType = 1; else currentType = 2; if (currentType < prevType) { isValid = false; console.log(`❌ 错误: "${song}" (类型 ${currentType}) 出现在类型 ${prevType} 之后`); } prevType = currentType; } if (isValid) { console.log('✅ 排序规则验证通过!'); console.log(' - 数字优先'); console.log(' - 字母次之'); console.log(' - 其他符号最后'); } else { console.log('❌ 排序规则验证失败!'); } console.log('\n' + '='.repeat(60)); console.log('🎵 测试完成!'); console.log('='.repeat(60) + '\n'); // 导出函数供其他模块使用 if (typeof module !== 'undefined' && module.exports) { module.exports = { smartSort }; }