Hedge
Hedge

Reputation: 16768

Group and sum time series data with LoDash

I want to group this data by ISO week and sum up the registrations. How can I do this with LoDash? My latest solution and sample data looks like this:

const registrationJson = [ 
  { date: 2018-02-19T00:00:00.000Z, registrations: '7' },
  { date: 2018-02-20T00:00:00.000Z, registrations: '1' },
  { date: 2018-02-21T00:00:00.000Z, registrations: '3' },
  { date: 2018-02-22T00:00:00.000Z, registrations: '4' },
  { date: 2018-02-23T00:00:00.000Z, registrations: '1' },
  { date: 2018-02-28T00:00:00.000Z, registrations: '3' },
  { date: 2018-03-08T00:00:00.000Z, registrations: '1' } ]

const groupedResults = _(registrationJson)
  .groupBy("date")
  .map(item => {
    return {
      date: moment(item["date"])
        .startOf("isoWeek")
        .toString(),
      registrations: _.sumBy(item, "registrations")
    }
  })
  .value()

This however returns to wrong output:

[ { date: 'Mon Mar 12 2018 00:00:00 GMT+0100',
    registrations: '7' },
  { date: 'Mon Mar 12 2018 00:00:00 GMT+0100',
    registrations: '1' },
  { date: 'Mon Mar 12 2018 00:00:00 GMT+0100',
    registrations: '3' },
  { date: 'Mon Mar 12 2018 00:00:00 GMT+0100',
    registrations: '4' },
  { date: 'Mon Mar 12 2018 00:00:00 GMT+0100',
    registrations: '1' },
  { date: 'Mon Mar 12 2018 00:00:00 GMT+0100',
    registrations: '3' },
  { date: 'Mon Mar 12 2018 00:00:00 GMT+0100',
    registrations: '1' } ]

Upvotes: 2

Views: 1217

Answers (2)

skyboyer
skyboyer

Reputation: 23763

Your code's current version works next way: first group by date(not by week!) and then transforming elements with map. And since each date is unique in that list your grouping is useless. Do it in reverse order:

const registrationJson = [ 
      { date: 2018-02-19T00:00:00.000Z, registrations: '7' },
      { date: 2018-02-20T00:00:00.000Z, registrations: '1' },
      { date: 2018-02-21T00:00:00.000Z, registrations: '3' },
      { date: 2018-02-22T00:00:00.000Z, registrations: '4' },
      { date: 2018-02-23T00:00:00.000Z, registrations: '1' },
      { date: 2018-02-28T00:00:00.000Z, registrations: '3' },
      { date: 2018-03-08T00:00:00.000Z, registrations: '1' } ]

const groupedResults = _(registrationJson)
      .map(item => {
          return {
              date: moment(item["date"])
                    .startOf("isoWeek")
                    .toString(),
               registrations: parseInt(item.registrations)
          }
      })
      .groupBy("date")
      .mapValues(item => {
           /* 
            here for each isoWeek start as a key you will get 
            list of elements for the same week; item is an array
           */
           return _.sumBy(item, 'registrations');
       })
      .value()

Also be aware of data type. Since your registrations was a string it could result to concatenation instead of summing up.

Upvotes: 3

Zen
Zen

Reputation: 106

Could you try using single quotation mark in (item, 'registrations')?

Upvotes: 0

Related Questions