Я работаю над проектом, в котором пытаюсь составить график количества ежемесячных заказов, которые я получил. Мои текущие данные для ежемесячного заказа:
[
{
_id: { month: 12, year: 2021 },
year: 2021,
month: 'December',
orders: 1
},
{
_id: { month: 4, year: 2022 },
year: 2022,
month: 'April',
orders: 31
},
{
_id: { month: 5, year: 2022 },
year: 2022,
month: 'May',
orders: 2
}
]
Я хотел бы иметь массив со всеми пропущенными месяцами с orders: 0
, чтобы все месяцы, начиная с первого месяца/даты, были включены в диаграмму.
Я попытался сделать это:
let startYear = monthlyOrders[0]._id.year;
let startMonth = monthlyOrders[0]._id.month;
let endYear = monthlyOrders[monthlyOrders.length - 1]._id.year;
let endMonth = monthlyOrders[monthlyOrders.length - 1]._id.month;
let months = [
'January',
'February',
'March',
'April',
'May',
'June',
'July',
'August',
'September',
'October',
'November',
'December',
];
function getMonthlys () {
if (startYear === endYear) {
if (startMonth === endMonth) {
let date = {
month: startMonth,
year: startYear,
}
if (startMonth < endMonth) {
let months = 1;
while (months <= endMonth) {
months = months + 1;
}
let date =
{
month: months,
year: startYear,
}
}
}
}
}
Однако это, вероятно, не лучший способ сделать это, и я не уверен, как быть с датами, где startYear < endYear
, а startMonth === endMonth
.
Кроме того, чтобы справиться с добавлением 0 для заказов, когда их не существует, я попытался сделать это:
let monthsObj = [];
for (let i = startYear; i <= endYear; i++) {
for (let j = startMonth; j <= 12; j++) {
if (!(j > endMonth && i === endYear)) {
let obj = {
month: j,
year: i,
};
monthsObj.push(obj);
}
}
}
for (let dateVal of monthsObj) {
let isInArray = false;
for (let dayVal of monthlyOrders) {
if (dayVal._id.year == dateVal.year && dayVal._id.month == dateVal.month) {
isInArray = true;
}
}
if (isInArray === false) {
let obj = {
month: dateVal.month,
year: dateVal.year,
};
monthlyOrders.push({ _id: obj, year: dateVal.year, month: months[dateVal.month - 1], orders: 0 });
}
}
Я был бы очень признателен за любое предложение или о том, как получить:
[
{
_id: { month: 12, year: 2021 },
year: 2021,
month: 'December',
orders: 1
},
{
_id: { month: 1, year: 2022 },
year: 2022,
month: 'January',
orders: 0
},
{
_id: { month: 2, year: 2022 },
year: 2022,
month: 'February',
orders: 0
},
{
_id: { month: 3, year: 2022 },
year: 2022,
month: 'March',
orders: 0
},
{
_id: { month: 4, year: 2022 },
year: 2022,
month: 'April',
orders: 31
},
{
_id: { month: 5, year: 2022 },
year: 2022,
month: 'May',
orders: 2
}
]
массив, который мне нужен.
можно ли предположить, что даты в исходном массиве объектов отсортированы по дате?
@OctaviaSima Привет, да, я так думаю. Они взяты из базы данных mongodb, которую я собрал и отсортировал по месяцам и годам.
Вы можете использовать объект Date javascript, чтобы сравнить шаг по месяцам. Ваш код, я не мог сказать, что он делал каждый месяц, но он добавляет их в массив и возвращает его.
let startYear = 2021;
let startMonth = 6;
let endYear = 2023;
let endMonth = 2;
let months = [
'January',
'February',
'March',
'April',
'May',
'June',
'July',
'August',
'September',
'October',
'November',
'December',
];
function getMonthlys () {
var list = []
var startdate = new Date(startYear, startMonth, 1)
var enddate = new Date(endYear, endMonth, 1)
while (startdate < enddate) {
list.push({
month: startdate.getMonth(),
year: startdate.getFullYear()
})
startdate.setMonth(startdate.getMonth() + 1)
}
return list
}
var allmonths = getMonthlys();
Затем вам просто нужно найти данные за каждый из этих месяцев.
// for each month, find a match
var orders = allmonths.map( function(month) {
var match = datasrc.find(function(entry) {
return entry._id.month == month.month && entry._id.year == month.year
});
if (match) {
return match
}
else {
return {
_id: month,
month: months[month.month-1],
year: month.year,
orders: 0
}
}
})
Вы можете увидеть в этой скрипке https://jsfiddle.net/myt19j30/1/
However, this is probably not the best way to do this, and I am not sure how to deal with dates where startYear < endYear, but startMonth === endMonth.
Я думаю, что более простым подходом для каждой итерации цикла было бы добавление один объект к выходному массиву, а также отслеживание текущего индекса итерируемого входного массива. Если на итерации объект во входном массиве имеет совпадающие месяц и год, поместите его, в противном случае поместите объект-заполнитель (с учетом месяца с одним индексом). Затем, если итерируемый индекс является последним в исходном массиве, прерывается, в противном случае увеличивается месяц, а затем (при необходимости) год.
const monthlyOrders=[{_id:{month:12,year:2021},year:2021,month:"December",orders:1},{_id:{month:4,year:2022},year:2022,month:"April",orders:31},{_id:{month:5,year:2022},year:2022,month:"May",orders:2}];
const months=["January","February","March","April","May","June","July","August","September","October","November","December"];
let { year, month } = monthlyOrders[0]._id;
const endYear = monthlyOrders[monthlyOrders.length - 1]._id.year;
const endMonth = monthlyOrders[monthlyOrders.length - 1]._id.month;
const output = [];
let monthlyOrdersIndex = 0;
while (monthlyOrdersIndex !== monthlyOrders.length) {
// If the month/year we're on exists in the original array, use it:
if (year === monthlyOrders[monthlyOrdersIndex]._id.year && month === monthlyOrders[monthlyOrdersIndex]._id.month) {
output.push(monthlyOrders[monthlyOrdersIndex]);
monthlyOrdersIndex++;
} else {
output.push({
_id: { month, year },
year: year,
month: months[month - 1],
orders: 0
});
}
month = month === 12 ? 1 : month + 1;
if (month === 1) year++;
}
console.info(output);
Благодарю вас! Это намного менее запутанно и имеет гораздо больше смысла, чем то, как я думал об этом.
используйте объект JavaScript
Date
. Вы можете сравнить их, добавить 1 месяц и т. д.