ReactJS中按当前时间排序时间数组的异常问题排查
问题描述
在ReactJS中需要根据当前时间对时间数组进行排序,先对静态数组做了一次排序,再基于当前时间二次排序,但未得到正确结果。相关信息如下:
当前时间
14:51
原代码
// get the current date let currentDate = new Date(Date.now()); // format the current date to be as same as the date in the array (e.g 07:00 AM) let formattedCurrentDate = moment(currentDate).format('HH:MM '); let trips = [ '14:50 ', '15:18 ', '18:20 ', '15:48 ', '07:00 ', '09:40 ', '08:45 ', '18:00 ', '16:08 ', '16:18 ', '17:18 ', '10:00 ', ] as any; //I used the insertion sort to sort the array function sortedTrips(arr: any) { // Start from the second element. for (let i = 1; i < arr.length; i++) { // Go through the elements behind it. for (let j = i - 1; j > -1; j--) { // Value comparison with the formatted current Date if (arr[j + 1] > arr[j]) { // console.log('array time is less than Current Date', arr[j]); // Swap [arr[j + 1], arr[j]] = [arr[j], arr[j + 1]]; } else { // console.log('array time is greater than Current Date', arr[j]); } } } return arr; } const sortedArray = sortedTrips(trips); console.log('sortedArray', sortedArray); //Then I sorted the sorted array according to the current time function sortedCurrentTrips(arr: any) { for (let i = 1; i < arr.length; i++) { // Go through the elements behind it. for (let j = i - 1; j > -1; j--) { // Value comparison with the formatted current Date if (arr[j + 1] > formattedCurrentDate) { // console.log('array time is less than Current Date', arr[j]); // Swap [arr[j + 1], arr[j]] = [arr[j], arr[j + 1]]; } else { // console.log('array time is greater than Current Date', arr[j]); } } } return arr; } console.log('Final result', sortedCurrentTrips(sortedArray));
现有输出
排序后数组:
["18:20 ", "18:00 ", "17:18 ", "16:18 ", "16:08 ", "15:48 ", "15:18 ", "14:50 ", "10:00 ", "09:40 ", "08:45 ", "07:00 "]
最终结果:
["16:18 ", "17:18 ", "18:00 ", "18:20 ", "14:50 ", "15:18 ", "15:48 ", "16:08 ", "10:00 ", "09:40 ", "08:45 ", "07:00 "]
期望输出
["15:18 ", "15:48 ","16:08 ", "16:18 ", "17:18 ", "18:00 ", "18:20 ", "14:50 ", "10:00 ", "09:40 ", "08:45 ", "07:00 "]
问题分析
- 排序逻辑冗余且错误:两次插入排序完全没必要,第二次排序仅将大于当前时间的元素往前交换,但未维护这些元素内部的升序顺序,导致结果混乱。
- 字符串比较的局限性:虽然
HH:MM格式的字符串可以按字典序比较,但转换为数值(如当天总分钟数)进行比较更直观、可靠,避免字符串空格等细节干扰。
解决方案
通过一次排序完成需求,核心是将时间转换为可比较的数值,再按规则排序:
import moment from 'moment'; // 获取当前时间并转换为当天总分钟数 const currentMinutes = moment().hour() * 60 + moment().minute(); const trips = [ '14:50 ', '15:18 ', '18:20 ', '15:48 ', '07:00 ', '09:40 ', '08:45 ', '18:00 ', '16:08 ', '16:18 ', '17:18 ', '10:00 ', ]; // 将时间字符串转换为当天总分钟数的工具函数 const getTimeInMinutes = (timeStr) => { const [hour, minute] = timeStr.trim().split(':').map(Number); return hour * 60 + minute; }; // 一次排序完成需求 const sortedTrips = trips.sort((a, b) => { const aMinutes = getTimeInMinutes(a); const bMinutes = getTimeInMinutes(b); // 区分未来和过去时间 const isAFuture = aMinutes > currentMinutes; const isBFuture = bMinutes > currentMinutes; if (isAFuture && !isBFuture) { // A是未来时间,B是过去时间,A排前面 return -1; } else if (!isAFuture && isBFuture) { // B是未来时间,A是过去时间,B排前面 return 1; } else if (isAFuture && isBFuture) { // 都是未来时间,按升序排列(早的在前) return aMinutes - bMinutes; } else { // 都是过去时间,按降序排列(近的在前) return bMinutes - aMinutes; } }); console.log('最终结果', sortedTrips);
输出验证
运行上述代码,当前时间为14:51时,输出与期望一致:
["15:18 ", "15:48 ", "16:08 ", "16:18 ", "17:18 ", "18:00 ", "18:20 ", "14:50 ", "10:00 ", "09:40 ", "08:45 ", "07:00 "]
内容的提问来源于stack exchange,提问作者user14674901
相关产品推荐
相关产品推荐

