Как корректно нормализовать данные?

Просьба помочь со сложной нормализацией данных.

Проблема: С сервера приходит JSON c данными в виде массива объектов (в примере - rawData). У каждого объекта есть поле Id с ключом и поле Stats с массовом данных, которые нужно сгруппировать по Id.

Задача: Необходимо сгруппировать данные из масссива rawData по Id (необходимый результат в примере - result). *Условие - данные необходимо сформировать таким образом, чтобы при указании периода (в примере - startDate-endDate) в миллисекундах, в текущий массив данных добавлялся объект с пустыми значениями, если в исходных данных внутри rawData нет объекта с данными за эту дату.

Пример объекта с пустыми значениями:

[... { "Imp": 0, "Click": 0, "Ctr": 0, "date": "02.10.2018" }, ...]

Пользуюсь momentjs для работы с датами.

Пример (в примере просто фейковые данные для наглядности и результат может не сходиться с исходными данными):

https://repl.it/@sundeath/WorthlessLowLesson
  • Вопрос задан
  • 1100 просмотров
Пригласить эксперта
Ответы на вопрос 2
AngReload
@AngReload
Кратко о себе
const normalizeData = (startDate, endDate, rawData) => {
  const keys = ['Imp', 'Click', 'Ctr']
  const days = []
  let currentDate = new Date(startDate)
  const end = new Date(endDate)
  while (currentDate.getTime() < end.getTime()) {
    const dd = currentDate.getDate()
    const mm = currentDate.getMonth() + 1
    const yyyy = currentDate.getFullYear()
    days.push(`${dd < 10 ? '0' + dd : dd}.${mm < 10 ? '0' + mm : mm}.${yyyy}`)
    currentDate = new Date(yyyy, mm - 1, dd + 1)
  }
  const arrId = rawData.map(o => o.Id)
  const result = {}
  arrId.forEach(id => {
    result[id] = days.map(date => {
      const target = {date}
      keys.forEach(k => target[k] = 0)
      return target
    })
  })
  arrId.forEach((id, index) => {
    rawData[index].Stats.forEach(event => {
      const eventData = new Date(+event.CreateDate.match(/[0-9]+/));
      if (eventData.getTime() < startDate || eventData.getTime() > endDate) return null
      const dd = eventData.getDate()
      const mm = eventData.getMonth() + 1
      const yyyy = eventData.getFullYear()
      const str = `${dd < 10 ? '0' + dd : dd}.${mm < 10 ? '0' + mm : mm}.${yyyy}`
      const i = days.indexOf(str);
      result[id][i][event.Type] += event.Count
    })
  })
  return result
}

Вроде так.
Ответ написан
Комментировать
@davidnum95
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы