Data of Manipulating Arrays and Objects in JavaScript - javascript

I'm looking to perform some data manipulation of an object/array by somewhat transposing the values. where the values of the rows become columns. As an example i have original data which looks like this
[
{
"Team": "D PG",
"Original_x0020_Size_x0020__x0028": 194,
"Month": "January"
},
{ "Team": "D PP",
"Original_x0020_Size_x0020__x0028": 143,
"Month": "January"
},
{
"Team": "D RE",
"Original_x0020_Size_x0020__x0028": 19,
"Month": "January"
},
{
"Team": "D GP",
"Original_x0020_Size_x0020__x0028": 3,
"Month": "January"
},
{
"Team": "D PC",
"Original_x0020_Size_x0020__x0028": 2,
"Month": "January"
},
{
"Team": "D PT",
"Original_x0020_Size_x0020__x0028": 2,
"Month": "January"
},
{
"Team": "D PG",
"Original_x0020_Size_x0020__x0028": 35,
"Month": "February"
},
{
"Team": "D PP",
"Original_x0020_Size_x0020__x0028": 120,
"Month": "February"
},
{
"Team": "D RE",
"Original_x0020_Size_x0020__x0028": 40,
"Month": "February"
},
{
"Team": "D GP",
"Original_x0020_Size_x0020__x0028": 30,
"Month": "February"
},
{
"Team": "D PC",
"Original_x0020_Size_x0020__x0028": 9,
"Month": "February"
},
{
"Team": "D PT",
"Original_x0020_Size_x0020__x0028": 6,
"Month": "February"
}
]
My intention to change this to
//i'm looking at changing the original data to look like this. The Team will have a position on the array, for example array[0][1](this column will be taken by all values that belong to team 'D PG') and array[0][2](will be taken by all values that belong to the team 'D PP')
// you will notice that all the other values for other months are at zero, thats because i want the initial values to be zero untill data has been put in for them
[
[
"January",
194,
143,
19,
3,
2,
2
],
[
"February",
35,
120,
40,
30,
9,
6
],
[
"March",
0,
0,
0,
0,
0,
0
],
[
"April",
0,
0,
0,
0,
0,
0
],
[
"May",
0,
0,
0,
0,
0,
0
],
[
"June",
0,
0,
0,
0,
0,
0
],
[
"July",
0,
0,
0,
0,
0,
0
],
[
"August",
0,
0,
0,
0,
0,
0
],
[
"September",
0,
0,
0,
0,
0,
0
],
[
"October",
0,
0,
0,
0,
0,
0
],
[
"November",
0,
0,
0,
0,
0,
0
],
[
"December",
0,
0,
0,
0,
0,
0
]
]
i use a for Loop to iterate the original Data object and then use if statements to group them by Month and Team. But the code will become very bulky and i believe inefficient. Any ideas on a better way to do this
var grouped = eval('[["January",0,0,0,0,0,0],["February",0,0,0,0,0,0],["March"0,0,0,0,0,0],["April",0,0,0,0,0,0],["May",0,0,0,0,0,0],["June"0,0,0,0,0,0],["July",0,0,0,0,0,0],["August",0,0,0,0,0,0],["September",0,0,0,0,0,0],["October",0,0,0,0,0,0],["November",0,0,0,0,0,0],["December",0,0,0,0,0,0]]');
for (i=0; i< dataResult.length; i++) {
if((dataResult[i]['Month'] == 'January') && (dataResult[i]['Team'] == 'D PG')){
var original = dataResult[i]['Original_x0020_Size_x0020__x0028'];
grouped[0][1] =original;
}
if((dataResult[i]['Month'] == 'January') && (dataResult[i]['Team'] == 'D PP')){
var original = dataResult[i]['Original_x0020_Size_x0020__x0028'];
grouped[0][2] =original;
}
if((dataResult[i]['Month'] == 'January') && (dataResult[i]['Team'] == 'D RE')){
var original = dataResult[i]['Original_x0020_Size_x0020__x0028'];
grouped[0][3] =original;
}
if((dataResult[i]['Month'] == 'January') && (dataResult[i]['Team'] == 'D GP')){
var original = dataResult[i]['Original_x0020_Size_x0020__x0028'];
grouped[0][4] =original;
}
if((dataResult[i]['Month'] == 'January') && (dataResult[i]['Team'] == 'D PC')){
var original = dataResult[i]['Original_x0020_Size_x0020__x0028'];
grouped[0][5] =original;
}
if((dataResult[i]['Month'] == 'January') && (dataResult[i]['Team'] == 'D PT')){
var original = dataResult[i]['Original_x0020_Size_x0020__x0028'];
grouped[0][6] =original;
}

As always, just use a hashtable to easify things:
const result = [], month = {};
// I did not want to put that identifier everywhere... :/
const wtf = "Original_x0020_Size_x0020__x0028";
for(const entry of data){
if(month[entry.Month]){
month[entry.Month].push(entry[wtf]);
} else {
result.push(month[entry.Month] = [entry.Month, entry[wtf]]);
}
}

Related

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);

How to select multiple elements with xPath?

I'm using defiantjs to select elements in an object. This is my object:
{
"name": "Retail Sales",
"weight": 10,
"length": 6,
"type": "retailSales",
"rows": [
{
"dealerEvaluationHistoryID": 0,
"performanceDealerMappingDetailID": 14,
"month": 1,
"plan": 0,
"actual": 0,
"weight": 0,
"pelanggaranWilayah": 0
},
{
"dealerEvaluationHistoryID": 0,
"performanceDealerMappingDetailID": 14,
"month": 2,
"plan": 0,
"actual": 0,
"weight": 0,
"pelanggaranWilayah": 0
},
{
"dealerEvaluationHistoryID": 0,
"performanceDealerMappingDetailID": 14,
"month": 3,
"plan": 0,
"actual": 0,
"weight": 0,
"pelanggaranWilayah": 0
}
]
}
How do I select all month, plan, actual and weight inside each objects in row[]?
I'd like an output like this:
[[1,0,0,0],[2,0,0,0],[3,0,0,0]]
I can do //rows/month and //rows/plan but don't know how to do both.
You can use map method which applies a callback function for every item in the array.
Read more about map method.
let obj={
"name": "Retail Sales",
"weight": 10,
"length": 6,
"type": "retailSales",
"rows": [
{
"dealerEvaluationHistoryID": 0,
"performanceDealerMappingDetailID": 14,
"month": 1,
"plan": 0,
"actual": 0,
"weight": 0,
"pelanggaranWilayah": 0
},
{
"dealerEvaluationHistoryID": 0,
"performanceDealerMappingDetailID": 14,
"month": 2,
"plan": 0,
"actual": 0,
"weight": 0,
"pelanggaranWilayah": 0
},
{
"dealerEvaluationHistoryID": 0,
"performanceDealerMappingDetailID": 14,
"month": 3,
"plan": 0,
"actual": 0,
"weight": 0,
"pelanggaranWilayah": 0
}
]
}
let array=obj.rows.map(function(row){
return [row.month,row.plan,row.actual,row.weight];
});
console.log(JSON.stringify(array));

AmCharts - Help creating a trending bar

I'm trying to follow the docs on how to add a trending line on my serial type bar graph.
AmCharts.makeChart('chartdiv', {
type: 'serial',
addClassNames: true,
theme: 'light',
dataProvider: data,
startDuration: 1,
categoryField: 'month',
graphs: [
{
valueField: 'complaints',
type: 'column',
fillAlphas: 0.8,
balloonText: "# of complaints on [[category]]: <b>[[value]]</b>"
},
{
valueField: 'expectation',
type: 'line',
// bullet: 'round',
lineColor: 'green',
balloonText: "Expected less than <b>[[value]]</b> for [[category]]",
dashLengthField: "dashLengthLine"
}
],
categoryAxis: {
autoGridCount: false,
gridCount: data.length,
gridPosition: "start",
// labelRotation: 90
},
export: {
enabled: true
},
trendLines: [{
initialValue: 6,
finalValue: 8
}]
});
The trendingLines is not doing much there. I've tried in many ways to declare it, but no luck. Here's some of the data I'm working with:
[{
"expectation": 2,
"tendValue": 1,
"month": "January",
"complaints": 1
}, {
"expectation": 2,
"month": "February",
"complaints": 2
}, {
"expectation": 2,
"month": "March",
"complaints": 0
}, {
"expectation": 2,
"month": "April",
"complaints": 1
}, {
"expectation": 2,
"month": "May",
"complaints": 0
}, {
"expectation": 2,
"month": "June",
"complaints": 1
}, {
"expectation": 2,
"month": "July",
"complaints": 2
}, {
"expectation": 2,
"month": "August ",
"complaints": 1
}, {
"expectation": 2,
"month": "September",
"complaints": 3
}, {
"expectation": 2,
"month": "October",
"complaints": 1
}, {
"expectation": 2,
"month": "November",
"complaints": 2
}, {
"expectation": 2,
"tendValue": 3,
"month": "December",
"complaints": 3
} ]
What you're missing out is the declaration of a start and an end point. You only tell the trendline its values.
Minimum code for a trendline should be sth. like this:
{
"finalDate": "2012-01-22 12",
"finalValue": 10,
"initialDate": "2012-01-17 12",
"initialValue": 16
}
or in your case using initialCategory and finalCategory. Take a look at the class reference for more info on trendline parameters or look at this nice little demo.

Can we manage multiple highchart charts in a single function by changing type in chart drawing functionm

Is possible to group types of charts in high charts.?
I have json data, which I want to express in chart type. And also there is range slider.I need to give a option to select chart type by the end user. I have a dropdown list in which I populate some chart types like bar,pie,line etc. when user selects an option that corresponding chart type should be displayed. Is that possible with highchart?
Fiddle: http://jsfiddle.net/rahulsankarer/BqHLz/
Highcharts.setOptions({
chart: {
borderWidth: 5,
borderColor: '#e8eaeb',
borderRadius: 0,
backgroundColor: '#f7f7f7'
},
title: {
style: {
'fontSize': '1em'
},
useHTML: true,
x: -27,
y: 8,
text: 'Report'
}
});
var blogComments = [
{
"Name": "John",
"Month": "Jan",
"TotalWorkingDay": 12,
"Attendance": 1,
"Leave": 1
}, {
"Name": "John",
"Month": "Feb",
"TotalWorkingDay": 8,
"Attendance": 2,
"Leave": 1
},
{
"Name": "John",
"Month": "March",
"TotalWorkingDay": 10,
"Attendance": 0,
"Leave": 0
},
{
"Name": "John",
"Month": "April",
"TotalWorkingDay": 11,
"Attendance": 0,
"Leave": 0
},
{
"Name": "John",
"Month": "May",
"TotalWorkingDay": 8,
"Attendance": 0,
"Leave": 1
},
{
"Name": "David",
"Month": "Jan",
"TotalWorkingDay": 8,
"Attendance": 2,
"Leave": 3
},
{
"Name": "David",
"Month": "Feb",
"TotalWorkingDay": 5,
"Attendance": 1,
"Leave": 0
},
{
"Name": "David",
"Month": "March",
"TotalWorkingDay": 4,
"Attendance": 2,
"Leave": 0
},
{
"Name": "David",
"Month": "April",
"TotalWorkingDay": 1,
"Attendance": 1,
"Leave": 0
},
{
"Name": "David",
"Month": "May",
"TotalWorkingDay": 8,
"Attendance": 2,
"Leave": 0
},
{
"Name": "Sam",
"Month": "Jan",
"TotalWorkingDay": 7,
"Attendance": 0,
"Leave": 0
},
{
"Name": "Sam",
"Month": "Feb",
"TotalWorkingDay": 6,
"Attendance": 0,
"Leave": 0
},
{
"Name": "Sam",
"Month": "March",
"TotalWorkingDay": 11,
"Attendance": 0,
"Leave": 0
},
{
"Name": "Sam",
"Month": "April",
"TotalWorkingDay": 9,
"Attendance": 0,
"Leave": 0
},
{
"Name": "Sam",
"Month": "May",
"TotalWorkingDay": 2,
"Attendance": 0,
"Leave": 0
}
];
var newSeriesTotalWorkingDay = {
name: 'TotalWorkingDay',
data: []
};
var newSeriesAttendance = {
name: 'Attendance',
data: []
};
var newSeriesLeave = {
name: 'Leave',
data: []
};
var userNames = [];
var userNameMonths = [];
$.each(blogComments, function (index, User) {
// get the series
newSeriesTotalWorkingDay.data.push(User.TotalWorkingDay);
newSeriesAttendance.data.push(User.Attendance);
newSeriesLeave.data.push(User.Leave);
// Get the usernames
if (userNames[User.Name]) {
if (userNames[User.Name]['months']) {
userNames[User.Name]['months'][User.Month] = User.Month;
}
} else {
userNames[User.Name] = {
'months': []
};
userNames[User.Name]['months'][User.Month] = User.Month;
}
});
//console.log(userNames);
var newCategories = [];
for (var name in userNames) {
if (userNames.hasOwnProperty(name)) {
var tempObj = {}
tempObj.name = name;
tempMonths = userNames[name]['months'].sort();
tempObj.categories = [];
for (var month in tempMonths) {
tempObj.categories.push({
name: month
});
}
newCategories.push(tempObj);
}
}
window.chart = new Highcharts.Chart({
chart: {
renderTo: "chart-more",
type: "column"
},
series: [newSeriesTotalWorkingDay, newSeriesAttendance, newSeriesLeave],
xAxis: {
categories: newCategories
}
});
<div>
<label>Select Chart Type :</label>
<select>
<option value="line">Line</option>
<option value="area">Area</option>
<option value="bar">Bar</option>
<option value="audi">Audi</option>
</select>
</div>
Demo: http://jsfiddle.net/robschmuecker/Umx5X/
Here I have demonstrated how you can listen to both the select change event and a click on the images to change the chart type dynamically.
$(document).ready(function () {
var initialChartType = 'area';
$('#top10_update').val(initialChartType);
var chartSelector = '#top10';
function changeChartType(myType) {
$(chartSelector).highcharts().series[0].update({
type: myType
});
}
$('#top10_update').on('change', function () {
var type = $(this).val();
changeChartType(type);
});
$('.set-chart').on('click', function () {
var type = $(this).data('chart-type');
changeChartType(type);
});
$(chartSelector).highcharts({
chart: {
type: initialChartType,
margin: [50, 50, 100, 80]
},
title: {
text: 'TOP10'
},
subtitle: {
text: ' '
},
credits: {
enabled: false
},
xAxis: {
categories: ['1', '2', '3', '4'],
labels: {
rotation: -45,
align: 'right',
style: {
fontSize: '13px',
fontFamily: 'Verdana, sans-serif'
}
}
},
yAxis: {
min: 0,
title: {
text: 'Ilość'
}
},
legend: {
enabled: false
},
tooltip: {
formatter: function () {
return '<b>' + this.x + '</b><br/>' +
'Ilość: ' + this.y;
}
},
series: [{
name: 'Ilość zgłoszeń, TOP10',
data: [1, 2, 3, 43],
dataLabels: {
enabled: true,
rotation: -90,
color: '#FFFFFF',
align: 'right',
x: 4,
y: 10,
style: {
fontSize: '13px',
fontFamily: 'Verdana, sans-serif'
}
}
}]
});
function ajax_update(date) {
$.ajax({
url: "index.php/ajax",
async: false,
method: 'post',
dataType: "json",
data: {
date: date
},
beforeSend: function () {
$('#loading').show();
$('#top10').highcharts().showLoading();
},
success: function (dane) {
$('#top10').highcharts().xAxis[0].setCategories(dane.top10.xlabel, false);
$('#top10').highcharts().series[0].setData(dane.top10.data);
$('#top10').highcharts().setTitle(null, {
text: 'Dane za: ' + date.replace('^', ' - ')
});
$('#top10').highcharts().hideLoading();
$('#loading').hide();
},
error: function (dane) {
alert(dane.responseText);
}
});
}
});
I recommend you to visit our demo:
http://jsfiddle.net/tZUp4/
which uses a series.update

How to convert json of one format to another format

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));

Categories