如何对含嵌套多日期数组的对象数组按日期拆分重组并排序?
问题
我从API获取了如下对象数组:
const schedules = [ { "_id": "6436b48b875967d0bea245b4", "service": "64246dc9a2d61593d103c749", "scheduledDates": [ { "date": "2023-04-17T18:00:00.000Z", "user": "643701f7e5f61e6760f4d1f3" }, { "date": "2023-04-12T18:00:00.000Z", "user": "643701f7e5f61e6760f4d1f3" } ] }, { "_id": "6436b48b875967d0bea245b5", "service": "64246dc9a2d61593d103c749", "scheduledDates": [ { "date": "2023-04-19T10:30:00.000Z", "user": "64217a8dcc69c5fa48a5b484" }, { "date": "2023-04-12T18:00:00.000Z", "user": "6414be936b0bbf2bd8fa964f" } ] }, ]
我希望将该数组按scheduledDates中的date字段全局排序,最终拆分为每个scheduledDates元素单独对应一个原结构对象的数组,结果如下:
const newSchedules = [ { "_id": "6436b48b875967d0bea245b4", "service": "64246dc9a2d61593d103c749", "scheduledDates": [ { "date": "2023-04-12T18:00:00.000Z", "user": "643701f7e5f61e6760f4d1f3" } ] }, { "_id": "6436b48b875967d0bea245b5", "service": "64246dc9a2d61593d103c749", "scheduledDates": [ { "date": "2023-04-12T18:00:00.000Z", "user": "6414be936b0bbf2bd8fa964f" } ] }, { "_id": "6436b48b875967d0bea245b4", "service": "64246dc9a2d61593d103c749", "scheduledDates": [ { "date": "2023-04-17T18:00:00.000Z", "user": "643701f7e5f61e6760f4d1f3" } ] }, { "_id": "6436b48b875967d0bea245b5", "service": "64246dc9a2d61593d103c749", "scheduledDates": [ { "date": "2023-04-19T10:30:00.000Z", "user": "64217a8dcc69c5fa48a5b484" } ] }, ]
我编写的排序函数只能对每个对象内部的scheduledDates数组排序,无法实现全局排序和结构转换:
const handleSort = () => { if (sortOrder === "asc") { setSortOrder("desc"); return schedules.map((schedule) => schedule.scheduledDates.sort((a, b) => new Date(a.date) - new Date(b.date)) ); } else { setSortOrder("asc"); return schedules.map((schedule) => schedule.scheduledDates.sort((a, b) => new Date(b.date) - new Date(a.date)) } };
请问该如何解决?
解决方案
要实现需求,需要分三步处理:
- 扁平化结构:把每个
schedule对象的scheduledDates数组拆分成单个元素,每个元素对应一个独立的schedule对象副本 - 全局排序:基于拆分后每个对象的
scheduledDates[0].date进行排序 - 切换排序方向:根据当前
sortOrder控制升序/降序
修改后的handleSort函数如下:
const handleSort = () => { // 第一步:扁平化数组,将每个scheduledDates元素转为独立对象 const flattened = schedules.flatMap(schedule => schedule.scheduledDates.map(dateItem => ({ ...schedule, scheduledDates: [dateItem] // 保留原结构,仅包含单个日期项 })) ); // 第二步:根据日期排序,切换升降序 const sorted = flattened.sort((a, b) => { const dateA = new Date(a.scheduledDates[0].date); const dateB = new Date(b.scheduledDates[0].date); return sortOrder === "asc" ? dateB - dateA : dateA - dateB; }); // 第三步:切换排序状态并返回结果 setSortOrder(prev => prev === "asc" ? "desc" : "asc"); return sorted; };
代码说明
- flatMap+map:
flatMap遍历原数组并将每个对象的scheduledDates拆分为多个对象,避免嵌套数组;map为每个日期项创建原schedule的副本,确保不修改原数据 - 排序逻辑:直接基于拆分后每个对象的唯一日期项进行比较,实现全局排序;通过
sortOrder判断是升序(dateA - dateB)还是降序(dateB - dateA) - 状态切换:使用函数式更新
setSortOrder(prev => ...)确保状态更新的准确性
内容的提问来源于stack exchange,提问作者BraulioPortela
相关产品推荐
相关产品推荐

