poopoo
poopoo

Reputation: 43

Group object values by date

I'm trying to make an upcoming event on react native, I have this object

const calendatData = [
        {
            "data": [
              {
                "id": 25,
                "title": "Spotify",
                "name": "Family",
                "service_id": 1,
                "repetition": "Monthly",
                "price": "79000",
                "upcoming_date": [
                  "2020-08-07T13:35:44.606Z"
                ]
              },
              {
                "id": 26,
                "title": "Netflix",
                "name": "Mobile",
                "service_id": 2,
                "repetition": "Monthly",
                "price": "49000",
                "upcoming_date": [
                  "2020-08-18T13:35:44.600Z",
                  "2020-08-07T13:35:44.606Z"
                ]
              },
              {
                "id": 27,
                "title": "iTunes",
                "name": "Weekly Special",
                "service_id": 3,
                "repetition": "Weekly",
                "price": "22000",
                "upcoming_date": [
                  "2020-08-07T13:35:44.606Z",
                  "2020-08-14T13:35:44.606Z",
                  "2020-08-21T13:35:44.606Z",
                  "2020-08-28T13:35:44.606Z"
                ]
              }
            ],
            "status": "success"
          }
    ]

what I've been trying to do is to extract that object based on the upcoming_date. the result that I need is like this

upcomingData = [
        {
            date: '2020-08-07',
            title: [
                'Spotify',
                'Netflix',
                'iTunes'
            ]
        },
        {
            date: '2020-08-18',
            title: ['Netflix']
        },
        {
            date: '2020-08-14',
            title: ['iTuunes']
        },
        {
            date: '2020-08-21',
            title: ['iTuunes']
        },
        {
            date: '2020-08-28',
            title: ['iTuunes']
        }
]

On the same date, if there are multiple titles, it should be grouped under the same date in the object.

instead what I got was this object

upcomingData = [
    {
        title: [
            "Spotify",
            "Netflix",
            "iTunes",
        ],
        date : [
            "2020-08-29",
            "2020-08-07",
            "2020-08-18",
            "2020-08-07",
            "2020-08-07",
            "2020-08-14",
            "2020-08-21",
            "2020-08-28",
        ]
    }
]

I am new to this, and I'm aware that this is mostly about javascript knowledge, any help would be appreciated.

thanks

Upvotes: 2

Views: 230

Answers (2)

Shahnawaz Hossan
Shahnawaz Hossan

Reputation: 2720

The ideas are:

  • First, iterate your object by Array.prototype.map() and set a unique map key from the converted date.
  • Then push the title to every map's key.

Actually your final map(here is myMap) will be your expected upcomingData. To output as your expected object, you can make it in your own way.

const calendarData = [{ "data": [{ "id": 25, "title": "Spotify", "name": "Family", "service_id": 1, "repetition": "Monthly", "price": "79000", "upcoming_date": ["2020-08-07T13:35:44.606Z"] }, { "id": 26, "title": "Netflix", "name": "Mobile", "service_id": 2, "repetition": "Monthly", "price": "49000", "upcoming_date": ["2020-08-18T13:35:44.600Z", "2020-08-07T13:35:44.606Z"] }, { "id": 27, "title": "iTunes", "name": "Weekly Special", "service_id": 3, "repetition": "Weekly", "price": "22000", "upcoming_date": ["2020-08-07T13:35:44.606Z", "2020-08-14T13:35:44.606Z", "2020-08-21T13:35:44.606Z", "2020-08-28T13:35:44.606Z"] }], "status": "success" }];

var myMap = new Map();

calendarData[0].data.map(element => {

    var dates = [];

    element.upcoming_date.map(date => {

        var upcoming_date = date.slice(0,10);

        if (!myMap.get(upcoming_date)) {
            myMap.set(upcoming_date, []);
        }

        dates.push(upcoming_date);

    });

    var len = dates.length;

    for (let i = 0; i < len; i++) {
        myMap.get(dates[i]).push(element.title);
    }
});

var upcomingData = [];

for (const entry of myMap.entries()) {
    var obj = {};
    obj["date"] = entry[0];
    obj["title"] = entry[1];
    upcomingData.push(obj);
}

console.log(upcomingData);

Upvotes: 3

Yevhen Horbunkov
Yevhen Horbunkov

Reputation: 15530

You may

  • traverse your source array with Array.prototype.reduce() building up the Map where trimmed portion of your date string is used as a key and the object of desired format as a value
  • extract Map values, using Map.prototype.values() into resulting array

Following is a quick live demo:

const src = [{"data":[{"id":25,"title":"Spotify","name":"Family","service_id":1,"repetition":"Monthly","price":"79000","upcoming_date":["2020-08-07T13:35:44.606Z"]},{"id":26,"title":"Netflix","name":"Mobile","service_id":2,"repetition":"Monthly","price":"49000","upcoming_date":["2020-08-18T13:35:44.600Z","2020-08-07T13:35:44.606Z"]},{"id":27,"title":"iTunes","name":"Weekly Special","service_id":3,"repetition":"Weekly","price":"22000","upcoming_date":["2020-08-07T13:35:44.606Z","2020-08-14T13:35:44.606Z","2020-08-21T13:35:44.606Z","2020-08-28T13:35:44.606Z"]}],"status":"success"}],
    
    result = [...src[0].data
      .reduce((r,{upcoming_date, title}) => (
         upcoming_date.forEach((s,_,__,date=s.slice(0,10)) =>
            r.set(
              date, 
              {date, title: [...(r.get(date)?.title||[]), title]}
            )),r),
         new Map())
      .values()
    ]
    
console.log(result)
.as-console-wrapper{min-height:100%;}

Upvotes: 2

Related Questions