Подсчитывать объекты (в массиве), имеющие временные метки за последние несколько дней, недель и месяцев с момента «текущего времени»

#javascript #node.js #reactjs #momentjs #lodash

#javascript #node.js #reactjs #momentjs #Lodash

Вопрос:

У меня есть массив объектов с временными метками в качестве свойства:

Пример ввода:

 const data = [
  {
    _id: "602102db3acc4515d4b2f687",
    createdDt: "2021-02-08T09:22:35.000Z",
  },
  {
    _id: "6021024da706a260d8932da2",
    createdDt: "2021-02-08T09:20:13.000Z",
  },
  // ...
  // ...
  {
    _id: "6020fd863acc4515d4b2f685",
    createdDt: "2021-02-08T08:59:50.000Z",
  },
];
 

Теперь, начиная с текущей даты, мне нужно количество общих объектов с временными метками этого дня, предыдущего дня и так далее (количество может быть равно нулю, если в предыдущий день записи не было).

Точно так же мне нужны подсчеты за этот день, предыдущий день и так далее, то же самое с неделями и месяцами.

Например, результат, который я ожидаю, может быть следующим:

Пример вывода:

 const result = {
  days: [0, 0, 5, 10, ...],
  weeks: [15, 5, 8, 0, ...],
  months: [30, 42, 33, 23, ...]
}
 

Я использую ES6, Lodash и moment.js . Это для базового графического представления.


Обновить:

Это код, который я написал, может кто-нибудь предложить более простое решение?

Мое текущее решение:

 for (var i = 0, k = 1; i < 365; i  , k  ) {
  let dt = moment().subtract(i, "days");
  let td = moment().subtract(k, "days");
  builddays.push(0);
  for (var j = 0; j < drivers.length; j  ) {
    let ddt = new Date(drivers[j].createdDt);
    if (moment(ddt).isBetween(td, dt)) builddays[i] = drivers[j].count;
  }
}

var weeksbifurcate = builddays.reduce((resultArray, item, index) => {
  const chunkIndex = Math.floor(index / 7);

  if (!resultArray[chunkIndex]) {
    resultArray[chunkIndex] = [];
  }

  resultArray[chunkIndex].push(item);

  return resultArray;
}, []);

var monthsbifurcate = builddays.reduce((resultArray, item, index) => {
  const chunkIndex = Math.floor(index / 30);

  if (!resultArray[chunkIndex]) {
    resultArray[chunkIndex] = [];
  }

  resultArray[chunkIndex].push(item);

  return resultArray;
}, []);

for (i = 0; i < 12; i  ) {
  days.push(builddays[i]);
  weeks.push(weeksbifurcate[i].reduce(getSum, 0));
  months.push(monthsbifurcate[i].reduce(getSum, 0));
}
 

Комментарии:

1. Поэтому используйте reduce… повторите цикл и измените createdDt на дату. Определите разницу во времени (дата — сейчас), а затем определите, в каком сегменте он должен быть…

Ответ №1:

Используйте moment # diff, чтобы найти индексы, dayIndex т. Е. weekIndex , monthIndex и поместить или увеличить право index в соответствующий array result объект in:

 const solve = (data) => {
  const result = {
    days: [],
    weeks: [],
    months: [],
  };
  data.forEach((item) => {
    const today = moment();
    const createdDt = moment(item.createdDt);

    const dayIndex = today.diff(createdDt, "days");
    const weekIndex = today.diff(createdDt, "weeks");
    const monthIndex = today.diff(createdDt, "months");

    result.days[dayIndex] = (result.days[dayIndex] || 0)   1;
    result.weeks[weekIndex] = (result.weeks[weekIndex] || 0)   1;
    result.months[monthIndex] = (result.months[monthIndex] || 0)   1;
  });
  return resu<
};

const data = [
  {createdDt: "2021-03-03T00:00:00.000Z",},
  {createdDt: "2021-03-03T00:00:00.000Z",},
  {createdDt: "2021-03-01T00:00:00.000Z",},
  {createdDt: "2021-02-28T00:00:00.000Z",},
  {createdDt: "2021-02-27T00:00:00.000Z",},
  {createdDt: "2021-02-27T00:00:00.000Z",},
  {createdDt: "2021-02-27T00:00:00.000Z",},
  {createdDt: "2021-02-24T00:00:00.000Z",},
  {createdDt: "2021-02-23T00:00:00.000Z",},
];

console.log(solve(data)); 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js"></script> 

В результате может быть несколько undefined значений, но нет необходимости устанавливать для 0 него значение, поскольку оно может рассматриваться как 0 везде, где вы собираетесь его показывать / использовать.