我有一个以日期作为属性的普通对象数组,并希望根据该日期和特定日期类别来转换该数组。
const orders = [
{
"order_id": "1",
"description": "Description 1",
"date": "2024-02-03T19:00:57.744Z",
},
{
"order_id": "2",
"description": "Description 2",
"date": "2024-02-04T19:00:57.744Z",
},
{
"order_id": "3",
"description": "Description 3",
"date": "2024-02-06T19:00:57.744Z",
},
]
除此之外,我还有一个日期类别如下:
const category = [
'Overdue',
'Today',
'Tomorrow',
'This Week',
'Next Week',
'This Month',
'Next Month',
'Later',
'No Date',
];
我需要转换具有特定日期类别的新数组,并且类别只能以这种方式排序(增加日期)。
预期输出:
[
{
"category": "Today",
"data": [
{
"order_id": "1",
"description": "Description 1",
"date": "2024-02-03T19:00:57.744Z"
}
]
},
{
"category": "Tomorrow",
"data": [
{
"order_id": "2",
"description": "Description 2",
"date": "2024-02-04T19:00:57.744Z"
}
]
},
{
"category": "This Week",
"data": [
{
"order_id": "3",
"description": "Description 3",
"date": "2024-02-06T19:00:57.744Z"
}
]
}
]
我使用 dayjs 进行日期操作,并使用以下函数来检查特定类别的日期
const getCategoryByDate = date => {
if (date === null || date === undefined) {
return 'No Date';
}
const isToday = dayjs(date).isToday();
const isTomorrow = dayjs(date).isTomorrow();
const overdue = dayjs().isAfter(date, 'day');
const isThisYear = dayjs().year() === dayjs(date).year();
const isThisWeek = isThisYear && dayjs().isoWeek() === dayjs(date).isoWeek();
const isNextWeek = isThisYear && dayjs().isoWeek() + 1 === dayjs(date).isoWeek();
const isThisMonth = isThisYear && dayjs().month() === dayjs(date).month();
const isNextMonth = isThisYear && dayjs().month() + 1 === dayjs(date).month();
if (overdue) {
return 'Overdue';
} else if (isToday) {
return 'Today';
} else if (isTomorrow) {
return 'Tomorrow';
} else if (isThisWeek) {
return 'This Week';
} else if (isNextWeek) {
return 'Next Week';
} else if (isThisMonth) {
return 'This Month';
} else if (isNextMonth) {
return 'Next Month';
}
return 'Later';
};
最后使用 array.reduce 函数来转换新的所需数组
const output = orders.reduce((acc, curr) => {
const {date} = curr;
const category = getCategoryByDate(date);
const found = acc.find((item) => item.category === category);
if (found) {
found.data.push(curr);
} else {
const obj = {category: category, data: [curr]};
acc = [obj];
}
return acc;
}, []);
这样,我没有得到想要的结果,如果
output
数组之前未排序,则 order
数组不会根据类别按顺序排序。
将类别转换为具有日期值的对象(使用 dayjs 或 vanilla js 将它们生成为字符串),然后使用
Array::findLast()
查找类别。
这比每次比较时调用日期函数的性能更高。
如果您的日期未排序,请稍后根据类别的索引键对它们进行排序。
const orders = [
{
"order_id": "1",
"description": "Description 1",
"date": "2024-02-03T19:00:57.744Z",
},
{
"order_id": "2",
"description": "Description 2",
"date": "2024-02-04T19:00:57.744Z",
},
{
"order_id": "3",
"description": "Description 3",
"date": "2024-02-06T19:00:57.744Z",
},
];
// generate dynamically
const categories = {
Today: '2024-02-03',
Tomorrow: '2024-02-04',
'This week': '2024-02-05',
// add more entries
};
const result = orders.reduce(((map, categories) => (r, item) => {
if(!item.date){
// add to no date cateogory
return r;
}
const cat = categories.findLast(([title, date]) => date < item.date);
if(!cat){
// add to overdue category
return r;
}
(map[cat[0]] ??= r[r.length] = {category: cat[0], data: []}).data.push(item);
return r;
})({}, Object.entries(categories)), []);
console.log(result);