Получение недостающих месяцев

Я работаю над проектом, в котором пытаюсь составить график количества ежемесячных заказов, которые я получил. Мои текущие данные для ежемесячного заказа:

[
  {
    _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
  }
]

массив, который мне нужен.

используйте объект JavaScript Date. Вы можете сравнить их, добавить 1 месяц и т. д.

Garr Godfrey 07.05.2022 02:31

можно ли предположить, что даты в исходном массиве объектов отсортированы по дате?

Octavia Sima 07.05.2022 02:35

@OctaviaSima Привет, да, я так думаю. Они взяты из базы данных mongodb, которую я собрал и отсортировал по месяцам и годам.

Gigi101 07.05.2022 02:38
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
3
34
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вы можете использовать объект 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);

Благодарю вас! Это намного менее запутанно и имеет гораздо больше смысла, чем то, как я думал об этом.

Gigi101 07.05.2022 02:58

Другие вопросы по теме