Tushar Khatiwada Tushar Khatiwada - 2 months ago 11
JSON Question

Formatting a JSON data using lodash

I have a JSON data with the following format:

activities

[
{
"id": 32,
"poi_id": 1,
"due_date": "2016-09-08T18:15:00.000Z",
"items": [
{
"id": 21,
"name": "Choluv jar : JAR",
"activity_id": 32
}
]
},
{
"id": 30,
"poi_id": 9,
"due_date": "2016-09-14T18:15:00.000Z",
"items": [
{
"id": 17,
"name": "Bourbon Family : PKT",
"activity_id": 30
},
{
"id": 18,
"name": "Choluv jar : JAR",
"activity_id": 30
}
]
},
{
"id": 29,
"poi_id": 1,
"due_date": "2016-09-27T18:15:00.000Z",
"items": [
{
"id": 16,
"name": "Choluv jar : JAR",
"activity_id": 29
}
]
}
]


I want to reformat this data using lodash or simply javascript to look like this:

/*poi_id is the key*/

"1": [{
"id": 32,
"poi_id": 1,
"due_date": "2016-09-08T18:15:00.000Z",
"items": {
/*due_date is the key*/

"2016-09-08T18:15:00.000Z": [{
"id": 21,
"name": "Choluv jar : JAR",
"activity_id": 32
}]
}
}, {
"id": 29,
"poi_id": 1,
"due_date": "2016-09-27T18:15:00.000Z",
"items": {
"2016-09-27T18:15:00.000Z": [{
"id": 16,
"name": "Choluv jar : JAR",
"activity_id": 29
}]
}
}],

"9": [{
"id": 30,
"poi_id": 9,
"due_date": "2016-09-14T18:15:00.000Z",
"items": {
"2016-09-14T18:15:00.000Z": [{
"id": 17,
"name": "Bourbon Family : PKT",
"activity_id": 30
}, {
"id": 18,
"name": "Choluv jar : JAR",
"activity_id": 30
}]
}
}]


All I want is to put the data that has the same poi_id under one collection with the
key
of poi_id and same for the items with same due_date.

Here's what I've done so far:

let activityArray = {};
_.forEach(activities, (activityItem) => {
if (!activityArray[activityItem.poi_id]) {
activityArray[activityItem.poi_id] = [];
}
activityArray[activityItem.poi_id].push(activityItem);
_.forEach(activityArray[activityItem.poi_id], (value, key) => {
activityArray[activityItem.poi_id][key].items.unshift(activityArray[activityItem.poi_id][key].due_date);
});
});


And this is what I got:

"1": [{
"id": 32,
"poi_id": 1,
"due_date": "2016-09-08T18:15:00.000Z",

/*unShift added due_date twice here, I want here key value pair*/

"items": [
"2016-09-08T18:15:00.000Z",
"2016-09-08T18:15:00.000Z", {
"id": 21,
"name": "Choluv jar : JAR",
"activity_id": 32
}
]
}, {
"id": 29,
"poi_id": 1,
"due_date": "2016-09-27T18:15:00.000Z",
"items": [
"2016-09-27T18:15:00.000Z", {
"id": 16,
"name": "Choluv jar : JAR",
"activity_id": 29
}
]
}],
"9": [{
"id": 30,
"poi_id": 9,
"due_date": "2016-09-14T18:15:00.000Z",
"items": [
"2016-09-14T18:15:00.000Z", {
"id": 17,
"name": "Bourbon Family : PKT",
"activity_id": 30
}, {
"id": 18,
"name": "Choluv jar : JAR",
"activity_id": 30
}
]
}]


I tried with other approaches too, but couldn't make it like the one I'm expecting.

Please guide me here.

Thanks.

Answer

A compact solution in plain Javascript with an object as hash for the items arrays.

var activities = [{ "id": 32, "poi_id": 1, "due_date": "2016-09-08T18:15:00.000Z", "items": [{ "id": 21, "name": "Choluv jar : JAR", "activity_id": 32 }] }, { "id": 30, "poi_id": 9, "due_date": "2016-09-14T18:15:00.000Z", "items": [{ "id": 17, "name": "Bourbon Family : PKT", "activity_id": 30 }, { "id": 18, "name": "Choluv jar : JAR", "activity_id": 30 }] }, { "id": 29, "poi_id": 1, "due_date": "2016-09-27T18:15:00.000Z", "items": [{ "id": 16, "name": "Choluv jar : JAR", "activity_id": 29 }] }],
    hash = {},
    grouped = {};

activities.forEach(a => {
    hash[a.poi_id] = hash[a.poi_id] || {};
    hash[a.poi_id][a.due_date] = hash[a.poi_id][a.due_date] || [];
    grouped[a.poi_id] = grouped[a.poi_id] || [];
    grouped[a.poi_id].push({
        id: a.id,
        poi_id: a.poi_id,
        due_date: a.due_date,
        items: { [a.due_date]: hash[a.poi_id][a.due_date] }
    });
    a.items.forEach(b => hash[a.poi_id][a.due_date].push(b));
});

console.log(grouped);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Comments