How to convert json of one format to another format - javascript

I have a json like
var UserMatrix =[{
ID: 1,
Name: "Sid Edelmann",
UPI: 20483,
Guru: "Yes",
Views: {
February: 12,
March: 8,
April: 10,
May: 11,
June: 8
},
Ratings: {
February: 1,
March: 2,
April: 0,
May: 0,
June: 0
},
Comments: {
February: 1,
March: 1,
April: 0,
May: 0,
June: 1
},
TotalViews: {
FebJune: 49
},
TotalRatings: {
FebJune: 3
},
AverageRatings: {
FebJune: '#'
},
TotalComments: {
FebJune: 3
}
},
{
ID: 6,
Name: "Parthasarathy Perumbali",
UPI: "999999",
Guru: "",
Views: {
February: "8",
March: "5",
April: "4",
May: "1",
June: "8"
},
Ratings: {
February: "2",
March: "1",
April: "2",
May: "1",
June: "2"
},
Comments: {
February: "3",
March: "0",
April: "0",
May: "0",
June: "0"
},
TotalViews: {
FebJune: "26"
},
TotalRatings: {
FebJune: "8"
},
AverageRatings: {
FebJune: "#"
},
TotalComments: {
FebJune: "3"
}
}
];
I want to convert this json to the following. How can I do this?
var blogComments = [
{
"Name": "Sid Edelmann",
"Month": "Feb",
"Views": 12,
"Ratings": 1,
"Comments": 1
}, {
"Name": "Sid Edelmann",
"Month": "Mar",
"Views": 8,
"Ratings": 2,
"Comments": 1
},
{
"Name": "Sid Edelmann",
"Month": "Apr",
"Views": 10,
"Ratings": 0,
"Comments": 0
},
{
"Name": "Sid Edelmann",
"Month": "May",
"Views": 11,
"Ratings": 0,
"Comments": 0
},
{
"Name": "Sid Edelmann",
"Month": "Jun",
"Views": 8,
"Ratings": 0,
"Comments": 1
},
{
"Name": "Parthasarathy Perumbali",
"Month": "Feb",
"Views": 8,
"Ratings": 2,
"Comments": 3
},
{
"Name": "Parthasarathy Perumbali",
"Month": "Mar",
"Views": 5,
"Ratings": 1,
"Comments": 0
},
{
"Name": "Parthasarathy Perumbali",
"Month": "Apr",
"Views": 4,
"Ratings": 2,
"Comments": 0
},
{
"Name": "Parthasarathy Perumbali",
"Month": "May",
"Views": 1,
"Ratings": 1,
"Comments": 0
},
{
"Name": "Parthasarathy Perumbali",
"Month": "Jun",
"Views": 8,
"Ratings": 2,
"Comments": 0
}
];

I made following code to work without jQuery.
The code contains comments so it is pretty self-explanatory. As a special note, my code works even if you have different number of months for different matrix entries as long as Views, Ratings and Comments has same amount of months inside one entry. I wanted to make this to work like this, because it is less hard-coded way of doing things.
See Js fiddle example and remember to open your developer console to see the results.
The code is also here, below:
// UserMatrix data....
var UserMatrix =[{
ID: 1,
Name: "Sid Edelmann",
UPI: 20483,
Guru: "Yes",
Views: {
February: 12,
March: 8,
April: 10,
May: 11,
June: 8
},
Ratings: {
February: 1,
March: 2,
April: 0,
May: 0,
June: 0
},
Comments: {
February: 1,
March: 1,
April: 0,
May: 0,
June: 1
},
TotalViews: {
FebJune: 49
},
TotalRatings: {
FebJune: 3
},
AverageRatings: {
FebJune: '#'
},
TotalComments: {
FebJune: 3
}
},
{
ID: 6,
Name: "Parthasarathy Perumbali",
UPI: "999999",
Guru: "",
Views: {
February: "8",
March: "5",
April: "4",
May: "1",
June: "8"
},
Ratings: {
February: "2",
March: "1",
April: "2",
May: "1",
June: "2"
},
Comments: {
February: "3",
March: "0",
April: "0",
May: "0",
June: "0"
},
TotalViews: {
FebJune: "26"
},
TotalRatings: {
FebJune: "8"
},
AverageRatings: {
FebJune: "#"
},
TotalComments: {
FebJune: "3"
}
}
];
/**
* Yay! Method for converting UserMatrix to blogComments
*
*/
function convertUserMatrixToBlogComments() {
// Final format
var blogComments = [],
// Current matrix entry
userMatrix,
// Months
months = {};
// Loop each object in UserMatrix
for(var i=0; i < UserMatrix.length; i++) {
// Current
userMatrix = UserMatrix[i];
// Find out months
for (var m in userMatrix.Views) {
if(userMatrix.Views.hasOwnProperty(m)) {
// Makes container for months
// e.g. February: "Feb"
months[m] = m.substring(0, 3);
}
};
// Go through all matrix data for months and push to comments
for(var j in months) {
if(months.hasOwnProperty(j)) {
blogComments.push({
Name: userMatrix.Name,
Month: months[j],
Views: parseInt(userMatrix.Views[j], 10),
Ratings: parseInt(userMatrix.Ratings[j], 10),
Comments: parseInt(userMatrix.Comments[j], 10)
});
}
}
// Next cycle starts here..
months = {};
}
// We are done!
return blogComments;
}
// Lets do this!
var blogComments = convertUserMatrixToBlogComments();
// See the results
console.log(blogComments);

Here you go.
newUsers = [];
$.each(UserMatrix, function (i, user) {
$.each(user.Views, function(key, value){
newUser = {};
newUser['Name'] = user['Name'];
newUser['Month'] = key;
newUser['Views'] = value;
newUser['Ratings'] = user.Ratings[key];
newUser['Comments'] = user.Comments[key];
newUsers.push(newUser);
});
});
console.log(JSON.stringify(newUsers));
Demo: http://jsfiddle.net/robschmuecker/Bc4hw/
Outputs:
[{
"Name": "Sid Edelmann",
"Month": "February",
"Views": 12,
"Ratings": 1,
"Comments": 1
}, {
"Name": "Sid Edelmann",
"Month": "March",
"Views": 8,
"Ratings": 2,
"Comments": 1
}, {
"Name": "Sid Edelmann",
"Month": "April",
"Views": 10,
"Ratings": 0,
"Comments": 0
}, {
"Name": "Sid Edelmann",
"Month": "May",
"Views": 11,
"Ratings": 0,
"Comments": 0
}, {
"Name": "Sid Edelmann",
"Month": "June",
"Views": 8,
"Ratings": 0,
"Comments": 1
}, {
"Name": "Parthasarathy Perumbali",
"Month": "February",
"Views": "8",
"Ratings": "2",
"Comments": "3"
}, {
"Name": "Parthasarathy Perumbali",
"Month": "March",
"Views": "5",
"Ratings": "1",
"Comments": "0"
}, {
"Name": "Parthasarathy Perumbali",
"Month": "April",
"Views": "4",
"Ratings": "2",
"Comments": "0"
}, {
"Name": "Parthasarathy Perumbali",
"Month": "May",
"Views": "1",
"Ratings": "1",
"Comments": "0"
}, {
"Name": "Parthasarathy Perumbali",
"Month": "June",
"Views": "8",
"Ratings": "2",
"Comments": "0"
}]

This should work for you
var result = [];
UserMatrix.forEach(function (user) {
var allMonths = Object.keys(user.Views);
allMonths.forEach(function(month){
var monthObject = {};
monthObject["Name"] = user.Name;
monthObject["Month"] = month.slice(0,3);
monthObject["Views"] = user.Views[month];
monthObject["Ratings"] = user.Ratings[month];
monthObject["Comments"] = user.Comments[month];
result.push(monthObject);
});
})
console.log(result);

Fiddle
var finalArr = [];
var months = ["February", "March", "April", "May", "June"];
UserMatrix.forEach(function (user) {
months.forEach(function (m) {
finalArr.push({
Name: user.Name,
Month: m,
Views: user.Views[m],
Ratings: user.Ratings[m],
Comments: user.Comments[m]
});
});
});
document.getElementById('op').innerHTML = JSON.stringify(finalArr);
console.log(finalArr);
Update
Specifying the months and attributes within an array might give you more flexibility while enhancing your application.
Fiddle
var finalArr = [];
var months = ["February", "March", "April", "May", "June"];
var attr = ["Views", "Ratings", "Comments"];
UserMatrix.forEach(function (user) {
months.forEach(function (m) {
var newObj = {};
newObj.Name=user.Name;
newObj.Month = m;
attr.forEach(function (a) {
newObj[a]=user[a][m];
});
finalArr.push(newObj);
});
});
document.getElementById('op').innerHTML = JSON.stringify(finalArr);
console.log(JSON.stringify(finalArr));

Related

Repetitive Query in MongoDB

I am creating a query in MongoDB which works correctly for me but in the end I have to do an extra grouping to get the response grouped by year. This is the query:
db.sales.aggregate([
{
$group: {
_id: {
month: {
$month: "$createdAt"
},
year: {
$year: "$createdAt"
},
dayOfWeek: {
$dayOfWeek: "$createdAt"
},
stringDay: {
$dateToString:
{ format: "%Y-%m-%d", date: "$createdAt"}
},
week: {
$isoWeek: "$createdAt"
}
},
total: { $sum: '$total'},
count: { $sum: 1 },
totalAverage: { $avg: '$total'}
}
},
{
$sort : {
"_id.month" : 1
}
},
{
$project: {
total: { $round: [ "$total", 2 ] },
year: "$_id.year",
date: "$_id.date",
week: "$_id.week",
numVentas: "$count",
month: "$_id.month",
dayOfWeek: "$_id.dayOfWeek",
stringDay:"$_id.stringDay",
count: "$count",
totalAverage: { $round: [ "$totalAverage", 2 ] },
stringMonth: {
$arrayElemAt: [
[
"",
"Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
"Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec"
],
"$_id.month"
]
},
stringWeek: {
$switch: {
branches:[
{ case: { $eq: ["$_id.dayOfWeek", 1] }, then: "Lunes" },
{ case: { $eq: ["$_id.dayOfWeek", 2] }, then: "Martes" },
{ case: { $eq: ["$_id.dayOfWeek", 3] }, then: "Miércoles" },
{ case: { $eq: ["$_id.dayOfWeek", 4] }, then: "Jueves" },
{ case: { $eq: ["$_id.dayOfWeek", 5] }, then: "Viernes" },
{ case: { $eq: ["$_id.dayOfWeek", 6] }, then: "Sábado" },
{ case: { $eq: ["$_id.dayOfWeek", 7] }, then: "Domingo" }
],
default: "Día desconocido"
}
}
}
},
{
$group: {
_id: { month: "$stringMonth", year: "$year"},
count: { $sum: "$count" },
total: { $sum: "$total" },
totalAverage: { $sum: "$totalAverage" },
sales: {
$push: {
numberDay: "$dayOfWeek",
stringWeek: "$stringWeek",
date: "$stringDay",
total: "$total",
count: "$count",
totalAverage: { $round: [ "$totalAverage", 2 ] }
}
}
}
},
{
$group: {
_id: "$_id.year",
monthsWithSales: { $sum: 1 },
count: { $sum: "$count" },
total: { $sum: "$total" },
totalAverage: { $sum: "$totalAverage" },
sales: {
$push: {
mes: "$_id.month",
count: "$count",
total: "$total",
totalAverage: "$totalAverage",
sales:"$sales"
}
}
}
}
])
And I get this response:
[
{
"_id": 2022,
"monthsWithSales": 4,
"count": 57,
"total": 22324.8,
"totalAverage": 7765.799999999999,
"sales": [
{
"mes": "Oct",
"count": 10,
"total": 1936,
"totalAverage": 1233.6,
"sales": [
{
"numberDay": 6,
"stringWeek": "Sábado",
"date": "2022-10-21",
"total": 526.8,
"count": 3,
"totalAverage": 175.6
},
{
"numberDay": 1,
"stringWeek": "Lunes",
"date": "2022-10-02",
"total": 85.6,
"count": 1,
"totalAverage": 85.6
},
{
"numberDay": 7,
"stringWeek": "Domingo",
"date": "2022-10-22",
"total": 526.8,
"count": 3,
"totalAverage": 175.6
},
{
"numberDay": 3,
"stringWeek": "Miércoles",
"date": "2022-10-04",
"total": 180,
"count": 1,
"totalAverage": 180
},
{
"numberDay": 4,
"stringWeek": "Jueves",
"date": "2022-10-12",
"total": 531.2,
"count": 1,
"totalAverage": 531.2
},
{
"numberDay": 3,
"stringWeek": "Miércoles",
"date": "2022-10-25",
"total": 85.6,
"count": 1,
"totalAverage": 85.6
}
]
},
{
"mes": "Nov",
"count": 7,
"total": 2205.2,
"totalAverage": 1014.8,
"sales": [
{
"numberDay": 4,
"stringWeek": "Jueves",
"date": "2022-11-02",
"total": 526.8,
"count": 3,
"totalAverage": 175.6
},
{
"numberDay": 6,
"stringWeek": "Sábado",
"date": "2022-11-25",
"total": 171.2,
"count": 2,
"totalAverage": 85.6
},
{
"numberDay": 7,
"stringWeek": "Domingo",
"date": "2022-11-12",
"total": 1507.2,
"count": 2,
"totalAverage": 753.6
}
]
},
{
"mes": "Dec",
"count": 33,
"total": 12587.6,
"totalAverage": 4074.5,
"sales": [
{
"numberDay": 3,
"stringWeek": "Miércoles",
"date": "2022-12-06",
"total": 850,
"count": 1,
"totalAverage": 850
},
{
"numberDay": 6,
"stringWeek": "Sábado",
"date": "2022-12-02",
"total": 8737.6,
"count": 25,
"totalAverage": 349.5
},
{
"numberDay": 7,
"stringWeek": "Domingo",
"date": "2022-12-10",
"total": 900,
"count": 1,
"totalAverage": 900
},
{
"numberDay": 1,
"stringWeek": "Lunes",
"date": "2022-12-04",
"total": 200,
"count": 1,
"totalAverage": 200
},
{
"numberDay": 2,
"stringWeek": "Martes",
"date": "2022-12-05",
"total": 500,
"count": 1,
"totalAverage": 500
},
{
"numberDay": 5,
"stringWeek": "Viernes",
"date": "2022-12-08",
"total": 250,
"count": 2,
"totalAverage": 125
},
{
"numberDay": 4,
"stringWeek": "Jueves",
"date": "2022-12-07",
"total": 250,
"count": 1,
"totalAverage": 250
},
{
"numberDay": 6,
"stringWeek": "Sábado",
"date": "2022-12-09",
"total": 900,
"count": 1,
"totalAverage": 900
}
]
},
{
"mes": "Sep",
"count": 7,
"total": 5596,
"totalAverage": 1442.8999999999999,
"sales": [
{
"numberDay": 2,
"stringWeek": "Martes",
"date": "2022-09-12",
"total": 5069.2,
"count": 4,
"totalAverage": 1267.3
},
{
"numberDay": 6,
"stringWeek": "Sábado",
"date": "2022-09-02",
"total": 526.8,
"count": 3,
"totalAverage": 175.6
}
]
}
]
},
{
"_id": 2021,
"monthsWithSales": 1,
"count": 2,
"total": 608,
"totalAverage": 608,
"sales": [
{
"mes": "Dec",
"count": 2,
"total": 608,
"totalAverage": 608,
"sales": [
{
"numberDay": 1,
"stringWeek": "Lunes",
"date": "2021-12-12",
"total": 171.2,
"count": 1,
"totalAverage": 171.2
},
{
"numberDay": 4,
"stringWeek": "Jueves",
"date": "2021-12-22",
"total": 436.8,
"count": 1,
"totalAverage": 436.8
}
]
}
]
}
]
It is correct, but as you can see at the end I make two groups to obtain the data grouped by year and then the sales array grouped by month.
Is there any way to improve this query without so much grouping?

How to update the page after call Axios.patch?

I made a line change via axios.path, but after changes in db.json I constantly need to reload the page. How can I avoid this and make the data update automatically?
const submitEdits = (item) => {
axios.patch(`http://localhost:3004/item/${item.id}`, { text: editingText })
setIdItem(null);
setEditingText('')
}
My db.json
{
"item": [
{
"text": "123123123",
"id": 0,
"data": {
"year": 2012,
"day": 25,
"month": 1
}
},
{
"text": "Поступил в институт",
"id": 1,
"data": {
"year": 2007,
"day": 12,
"month": 4
}
},
{
"id": 2,
"text": "123",
"data": {
"year": 2022,
"day": 16,
"month": 5
}
}
]
}

Javascript Filtering Array of Objects using Filter Question

I have 2 arrays of objects. Seen below
var subs = new Array();
var list_items = new Array();
subs = [
{ "value": 3, "text": "Guyana" },
{ "value": 4, "text": "St Lucia" },
{ "value": 5, "text": "Suriname" },
{ "value": 6, "text": "Barbados" },
{ "value": 7, "text": "3rd Party" },
{ "value": 8, "text": "JDL" }
];
list_items = [
{ "Id": 168, "Month": "May", "Resent": false, "Stage": "2", "StageRecipNum": 3, "Title": "Demand_Forecast_2020_Month_May", "parentID": "51" },
{ "Id": 169, "Month": "May", "Resent": false, "Stage": "2", "StageRecipNum": 4, "Title": "Demand_Forecast_2020_Month_May", "parentID": "51" },
{ "Id": 170, "Month": "May", "Resent": false, "Stage": "2", "StageRecipNum": 6, "Title": "Demand_Forecast_2020_Month_May", "parentID": "51" },
{ "Id": 171, "Month": "May", "Resent": false, "Stage": "2", "StageRecipNum": 5, "Title": "Demand_Forecast_2020_Month_May", "parentID": "51" }
];
What I'm trying to do is filter the "Subs" array, where any objects in the "list_items" array with the attribute ("StageRecipNum" matching the Subs "value" and "Resent" = false) should be removed from "Subs".
Here is the code I have to try to do this.
for (var i = 0; i < subs.length; i++) {
for (var j = 0; j < list_items.length; j++) {
if (parseInt(subs[i].value) == parseInt(list_items[j].StageRecipNum) &&
list_items[j].Resent == false) {
var hold = parseInt(list_items[j].StageRecipNum);
subs = subs.filter(el => el.value !== hold);
console.log(subs);
}
}
}
Afterward I am taking the remaining "Subs" array items and putting it in a dropdownlist to display on a form. All that works, the issue I am having is that one of the items in the list_items array keeps returning in the dropdownlist when it's not supposed to be there.
In the java console of visual studio code using Quokka, I get the below
As you can see, number 6 which is Barbados is not supposed to be there. I can't figure out why it's there and all the rest that not supposed to be in the array are not there. Only the 3rd Party and JDL supposed to be on the list.
I need help. What did I do wrong?
You can apply filter with some on the second array by matching StageRecipNum with value and resent property to be false. and once found take negate of some. Something like this:
const subs = [ { "value": 3, "text": "Guyana" }, { "value": 4, "text": "St Lucia" }, { "value": 5, "text": "Suriname" }, { "value": 6, "text": "Barbados" }, { "value": 7, "text": "3rd Party" }, { "value": 8, "text": "JDL" } ];
const list_items = [ { "Id": 168, "Month": "May", "Resent": false, "Stage": "2", "StageRecipNum": 3, "Title": "Demand_Forecast_2020_Month_May", "parentID": "51" }, { "Id": 169, "Month": "May", "Resent": false, "Stage": "2", "StageRecipNum": 4, "Title": "Demand_Forecast_2020_Month_May", "parentID": "51" }, { "Id": 170, "Month": "May", "Resent": false, "Stage": "2", "StageRecipNum": 6, "Title": "Demand_Forecast_2020_Month_May", "parentID": "51" }, { "Id": 171, "Month": "May", "Resent": false, "Stage": "2", "StageRecipNum": 5, "Title": "Demand_Forecast_2020_Month_May", "parentID": "51" } ];
const result = subs.filter(a=>!list_items.some(b=>b.StageRecipNum===a.value && b.Resent===false));
console.log(result);
You could take a Set and filter the array.
const
subs = [{ value: 3, text: "Guyana" }, { value: 4, text: "St Lucia" }, { value: 5, text: "Suriname" }, { value: 6, text: "Barbados" }, { value: 7, text: "3rd Party" }, { value: 8, text: "JDL" }],
list_items = [{ Id: 168, Month: "May", Resent: false, Stage: "2", StageRecipNum: 3, Title: "Demand_Forecast_2020_Month_May", parentID: "51" }, { Id: 169, Month: "May", Resent: false, Stage: "2", StageRecipNum: 4, Title: "Demand_Forecast_2020_Month_May", parentID: "51" }, { Id: 170, Month: "May", Resent: false, Stage: "2", StageRecipNum: 6, Title: "Demand_Forecast_2020_Month_May", parentID: "51" }, { Id: 171, Month: "May", Resent: false, Stage: "2", StageRecipNum: 5, Title: "Demand_Forecast_2020_Month_May", parentID: "51" }],
values = new Set(list_items.map(({ StageRecipNum }) => StageRecipNum)),
result = subs.filter(({ value }) => !values.has(value));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
The problem arises because you are altering the array which you are looping over. The loop ends prematurely, because the length of the array is no longer the original length after removing items, resulting in not evaluating the remaining items.
To keep using the same code, keep updating a copy of the array while keeping the subs variable in its original state.
Below a less verbose way of achieving the same result. Filter the list_items for values where Resent is false and select its StageRecipNum. Next, filter the subs for values where the value is not contained by the list items:
var subs = [
{ "value": 3, "text": "Guyana" },
{ "value": 4, "text": "St Lucia" },
{ "value": 5, "text": "Suriname" },
{ "value": 6, "text": "Barbados" },
{ "value": 7, "text": "3rd Party" },
{ "value": 8, "text": "JDL" }
];
var list_items = [
{ "Id": 168, "Month": "May", "Resent": false, "Stage": "2", "StageRecipNum": 3, "Title": "Demand_Forecast_2020_Month_May", "parentID": "51" },
{ "Id": 169, "Month": "May", "Resent": false, "Stage": "2", "StageRecipNum": 4, "Title": "Demand_Forecast_2020_Month_May", "parentID": "51" },
{ "Id": 170, "Month": "May", "Resent": false, "Stage": "2", "StageRecipNum": 6, "Title": "Demand_Forecast_2020_Month_May", "parentID": "51" },
{ "Id": 171, "Month": "May", "Resent": false, "Stage": "2", "StageRecipNum": 5, "Title": "Demand_Forecast_2020_Month_May", "parentID": "51" }
];
var list_item_nums = list_items.filter(x => !x.Resent).map(x => x.StageRecipNum);
var filtered_subs = subs.filter(x => !list_item_nums.includes(x.value));
console.log(filtered_subs);

Forming new array of objects and getting count of similar values

I am trying to form new array of objects using the old array object data. I want to get the average count of success and failure values.
//Old array of objects
[{
"id": "1",
"month": "MAR",
"description": "success",
"count": "100"
}, {
"id": "2",
"month": "APRIL",
"description": "success",
"count": "110"
}, {
"id": "3",
"month": "MAR",
"description": "failed",
"count": "50"
}, {
"id": "4",
"month": "MAR",
"description": "failed",
"count": "20"
}, {
"id": "5",
"month": "APRIL",
"description": "success",
"count": "100"
}, {
"id": "6",
"month": "APRIL",
"description": "failed",
"count": "80"
},
{
"id": "7",
"month": "MAR",
"description": "success",
"count": "300"
},
{
"id": "8",
"month": "APRIL",
"description": "failed",
"count": "40"
}
]
New array of objects to get average value of success and failed in each month
//new array of objects
[{
"month":"MAR",
"success":200 // 100+300/2
"failed":35 // 50+20/2
},
{
"month":"APRIL",
"success":105 // 100+110/2
"failed":60 // 40+80/2
}]
I have tried to get unique month and count of data, but I am not able to form the exact expected output. Any help will be really appreciated.
JSFIDDLE
Here is how you could do it with ES6, in a functional programming style:
function summary(data) {
return Array.from(new Set(data.map(o => o.month)), month =>
["failed", "success"].reduce( (acc, description) => {
const match = acc[1].filter(o => o.description == description)
.map(o => +o.count);
acc[0][description] = match.length
&& match.reduce((a,b) => a+b)/match.length;
return acc;
}, [{ month }, data.filter(o => o.month == month)] )[0]
);
}
const data = [{
"id": "1",
"month": "MAR",
"description": "success",
"count": "100"
}, {
"id": "2",
"month": "APRIL",
"description": "success",
"count": "110"
}, {
"id": "3",
"month": "MAR",
"description": "failed",
"count": "50"
}, {
"id": "4",
"month": "MAR",
"description": "failed",
"count": "20"
}, {
"id": "5",
"month": "APRIL",
"description": "success",
"count": "100"
}, {
"id": "6",
"month": "APRIL",
"description": "failed",
"count": "80"
}, {
"id": "7",
"month": "MAR",
"description": "success",
"count": "300"
}, {
"id": "8",
"month": "APRIL",
"description": "failed",
"count": "40"
}];
const result = summary(data);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Vanilla old-style Javascript approach:
var list = [{
"id": "1",
"month": "MAR",
"description": "success",
"count": "100"
}, {
"id": "2",
"month": "APRIL",
"description": "success",
"count": "110"
}, {
"id": "3",
"month": "MAR",
"description": "failed",
"count": "50"
}, {
"id": "4",
"month": "MAR",
"description": "failed",
"count": "20"
}, {
"id": "5",
"month": "APRIL",
"description": "success",
"count": "100"
}, {
"id": "6",
"month": "APRIL",
"description": "failed",
"count": "80"
},
{
"id": "7",
"month": "MAR",
"description": "success",
"count": "300"
},
{
"id": "8",
"month": "APRIL",
"description": "failed",
"count": "40"
}
];
var d = {};
for (var i=0,l; l = list[i]; i++) {
if (!d[l.month]) d[l.month] = {failed:0, fcount:0, success:0, scount:0};
if (l.description == 'failed') {
var c = d[l.month].fcount;
d[l.month].fcount++;
d[l.month].failed = d[l.month].failed * c / (c + 1) + l.count / (c + 1);
} else if (l.description == 'success') {
var c = d[l.month].scount;
d[l.month].scount++;
d[l.month].success = d[l.month].success * c / (c + 1) + l.count / (c + 1);
}
}
console.log(d);

Group values with the same key in an array of objects

To display data in highcharts.js I need to turn the following data:
"personas": [
{
"category":"Persona1",
"month":"6",
"week":"24",
"day":"18",
"dayaverage":0.5,
"weekaverage":1.33333333333333,
"monthaverage":1.53571428571429
},
{
"category":"Persona2",
"month":"6",
"week":"24",
"day":"18",
"dayaverage":0.146477031224456,
"weekaverage":0.194758246723904,
"monthaverage":0.601273296708939
},
{
"category":"Persona3",
"month":"6",
"week":"24",
"day":"18",
"dayaverage":1.25559947299078,
"weekaverage":1.43618513323983,
"monthaverage":0.998426393184655
},
{
"category":"Persona4",
"month":"6",
"week":"24",
"day":"18",
"dayaverage":0.799332962757087,
"weekaverage":0.923262727610554,
"monthaverage":0.769477297163179
},
{
"category":"Persona5",
"month":"6",
"week":"24",
"day":"18",
"dayaverage":0.669041769041769,
"weekaverage":0.67394482002558,
"monthaverage":0.670944920469891
},
{
"category":"Persona6",
"month":"6",
"week":"24",
"day":"18",
"dayaverage":0.656381486676017,
"weekaverage":0.722973507315144,
"monthaverage":0.69689774371321
},
{
"category":"Persona7",
"month":"6",
"week":"24",
"day":"18",
"dayaverage":0.540495407737267,
"weekaverage":0.576413277444205,
"monthaverage":0.693495281755596
}
]
Into this format:
[
{
name: 'dayaverage',
data: [0.5, 0.146477031224456, 1.25559947299078, 0.799332962757087, 0.669041769041769, 0.656381486676017, 0.540495407737267]
},
{
name: 'weekaverage',
data: [1.33333333333333, 0.194758246723904, 1.43618513323983, 0.923262727610554, 0.67394482002558, 0.722973507315144, 0.576413277444205]
}, {
name: 'monthaverage',
data: [1.53571428571429, 0.601273296708939, 0.998426393184655, 0.769477297163179, 0.670944920469891, 0.69689774371321, 0.693495281755596]
}
].
All I'm doing is grouping the dayaverage, weekaverage and monthaverage values into an array and specifying what they are with a name key-value pair.
I'm having trouble writing this because the parent function is going to call with a list of criteria (for the above example it was : criteria = ['dayaverage', 'weekaverage', 'monthaverage'];) and that could change.
Any help appreciated, thanks
You could use an array for the wanted properties and build an array with the data upon.
function getGrouped(array, groups) {
var grouped = groups.map(function (a) {
return { name: a, data: [] };
});
array.personas.forEach(function (a) {
groups.forEach(function (k, i) {
grouped[i].data.push(a[k]);
});
});
return grouped;
}
var data = { personas: [{ category: "Persona1", month: 6, week: 24, day: 18, dayaverage: 0.5, weekaverage: 1.33333333333333, monthaverage: 1.53571428571429 }, { category: "Persona2", month: 6, week: 24, day: 18, dayaverage: 0.146477031224456, weekaverage: 0.194758246723904, monthaverage: 0.601273296708939 }, { category: "Persona3", month: 6, week: 24, day: 18, dayaverage: 1.25559947299078, weekaverage: 1.43618513323983, monthaverage: 0.998426393184655 }, { category: "Persona4", month: 6, week: 24, day: 18, dayaverage: 0.799332962757087, weekaverage: 0.923262727610554, monthaverage: 0.769477297163179 }, { category: "Persona5", month: 6, week: 24, day: 18, dayaverage: 0.669041769041769, weekaverage: 0.67394482002558, monthaverage: 0.670944920469891 }, { category: "Persona6", month: 6, week: 24, day: 18, dayaverage: 0.656381486676017, weekaverage: 0.722973507315144, monthaverage: 0.69689774371321 }, { category: "Persona7", month: 6, week: 24, day: 18, dayaverage: 0.540495407737267, weekaverage: 0.576413277444205, monthaverage: 0.693495281755596 }] };
console.log(getGrouped(data, ['day', 'dayaverage', 'weekaverage', 'monthaverage']));
.as-console-wrapper { max-height: 100% !important; top: 0; }
You can do this using .map() along with .reduce() like so:
Also, to use dynamic properties, you can use bracket syntax ([]) for accessing properties on an object. Here, you can .map() your criteria list into the desired structure, and calculate the data using .reduce().
EDIT - Fixed resulting data structure to accurately output desired results
var personas = [{
"category": "Persona1",
"month": "6",
"week": "24",
"day": "18",
"dayaverage": 0.5,
"weekaverage": 1.33333333333333,
"monthaverage": 1.53571428571429
},
{
"category": "Persona2",
"month": "6",
"week": "24",
"day": "18",
"dayaverage": 0.146477031224456,
"weekaverage": 0.194758246723904,
"monthaverage": 0.601273296708939
},
{
"category": "Persona3",
"month": "6",
"week": "24",
"day": "18",
"dayaverage": 1.25559947299078,
"weekaverage": 1.43618513323983,
"monthaverage": 0.998426393184655
},
{
"category": "Persona4",
"month": "6",
"week": "24",
"day": "18",
"dayaverage": 0.799332962757087,
"weekaverage": 0.923262727610554,
"monthaverage": 0.769477297163179
},
{
"category": "Persona5",
"month": "6",
"week": "24",
"day": "18",
"dayaverage": 0.669041769041769,
"weekaverage": 0.67394482002558,
"monthaverage": 0.670944920469891
},
{
"category": "Persona6",
"month": "6",
"week": "24",
"day": "18",
"dayaverage": 0.656381486676017,
"weekaverage": 0.722973507315144,
"monthaverage": 0.69689774371321
},
{
"category": "Persona7",
"month": "6",
"week": "24",
"day": "18",
"dayaverage": 0.540495407737267,
"weekaverage": 0.576413277444205,
"monthaverage": 0.693495281755596
}
];
var criteria = ['dayaverage', 'weekaverage', 'monthaverage'];
function getMerged(objArr, criteria) {
var dataMap = objArr.reduce(function (result, current) {
criteria.forEach(function (elem) {
if (result[elem] != undefined) {
result[elem].push(current[elem]);
}
else {
result[elem] = [current[elem]];
}
});
return result;
}, {});
return criteria.map(function (elem) {
return {
name: elem,
data: dataMap[elem]
};
});
}
console.log(getMerged(personas, criteria));
One of the ways how to solve it, using Array#forEach.
var json = {personas:[{category:"Persona1",month:"6",week:"24",day:"18",dayaverage:.5,weekaverage:1.33333333333333,monthaverage:1.53571428571429},{category:"Persona2",month:"6",week:"24",day:"18",dayaverage:.146477031224456,weekaverage:.194758246723904,monthaverage:.601273296708939},{category:"Persona3",month:"6",week:"24",day:"18",dayaverage:1.25559947299078,weekaverage:1.43618513323983,monthaverage:.998426393184655},{category:"Persona4",month:"6",week:"24",day:"18",dayaverage:.799332962757087,weekaverage:.923262727610554,monthaverage:.769477297163179},{category:"Persona5",month:"6",week:"24",day:"18",dayaverage:.669041769041769,weekaverage:.67394482002558,monthaverage:.670944920469891},{category:"Persona6",month:"6",week:"24",day:"18",dayaverage:.656381486676017,weekaverage:.722973507315144,monthaverage:.69689774371321},{category:"Persona7",month:"6",week:"24",day:"18",dayaverage:.540495407737267,weekaverage:.576413277444205,monthaverage:.693495281755596}]},
criteria = ['dayaverage', 'weekaverage', 'monthaverage'],
arr = criteria.reduce(function(s,a){
s.push({name: a, data: []});
return s;
}, []);
arr.forEach(function(v) {
json.personas.forEach(function(c) {
v.data.push(c[v.name]);
})
})
console.log(arr);
try this:
var criteria = ['dayaverage', 'weekaverage', 'monthaverage']; //your dynamic criteria
var arr= []; //the filtered array you want
criteria.forEach(function(criterium){
// for each criterium you create a new object that you add to arr
arr.push({
name: criterium,
data: []
});
// then you populate the data field of the newly created field by browsing your big array "personas" that you need to parse before btw
personas.forEach(function (persona) {
arr[arr.length-1].data.push(persona[criterium]);
});
});
You can map the keys to an array of objects and map each of the objects' values by the current key in the mapping process.
var data = getData();
var modified = modify(data, 'personas', ['dayaverage', 'weekaverage', 'monthaverage']);
console.log(JSON.stringify(modified, null, 2));
function modify(data, root, keep) {
data = data[root] != null ? data[root] : data;
var keys = Object.keys(data[0]);
if (keep != null && keep.length > 0)
keys = keys.filter(key => keep.indexOf(key) > -1);
return keys.map(key => {
return {
name: key,
data: data.map(item => item[key])
}
});
}
function getData() {
return {
"personas": [{
"category": "Persona1",
"month": "6",
"week": "24",
"day": "18",
"dayaverage": 0.5,
"weekaverage": 1.33333333333333,
"monthaverage": 1.53571428571429
}, {
"category": "Persona2",
"month": "6",
"week": "24",
"day": "18",
"dayaverage": 0.146477031224456,
"weekaverage": 0.194758246723904,
"monthaverage": 0.601273296708939
}, {
"category": "Persona3",
"month": "6",
"week": "24",
"day": "18",
"dayaverage": 1.25559947299078,
"weekaverage": 1.43618513323983,
"monthaverage": 0.998426393184655
}, {
"category": "Persona4",
"month": "6",
"week": "24",
"day": "18",
"dayaverage": 0.799332962757087,
"weekaverage": 0.923262727610554,
"monthaverage": 0.769477297163179
}, {
"category": "Persona5",
"month": "6",
"week": "24",
"day": "18",
"dayaverage": 0.669041769041769,
"weekaverage": 0.67394482002558,
"monthaverage": 0.670944920469891
}, {
"category": "Persona6",
"month": "6",
"week": "24",
"day": "18",
"dayaverage": 0.656381486676017,
"weekaverage": 0.722973507315144,
"monthaverage": 0.69689774371321
}, {
"category": "Persona7",
"month": "6",
"week": "24",
"day": "18",
"dayaverage": 0.540495407737267,
"weekaverage": 0.576413277444205,
"monthaverage": 0.693495281755596
}]
};
}
.as-console-wrapper { top: 0; max-height: 100% !important; }

Categories