convert json object to specific json array - javascript

I have a json object {"yAxis" : { "Batting" : [10, 20, 30, 40] , "Bowling" : [10, 30, 50, 70], "Fielding" : [20, 40, 50, 70] } },
and want to convert to json array like this
[ { "name": "Batting" ,"data": [10,20,30,40]} , { "name": "Bowling" ,"data": [10,30,50,70] },{ "name": "Fielding" ,"data": [20,40,50,70]}]
I can create json object for each index but how can i put those to json array?
for(var abc in objJSON.yAxis)
{
seriesValues += JSON.stringify({name:abc,data:(objJSON.yAxis)[abc]});
}
Any help?

You can just loop through creating the object, don't worry about stringifying it.
var obj = {"yAxis" : { "Batting" : [10, 20, 30, 40] , "Bowling" : [10, 30, 50, 70], "Fielding" : [20, 40, 50, 70] } };
var keys = Object.keys(obj.yAxis),
narray = [];
keys.forEach(function(v) {
narray.push({ "name": v, "data": obj.yAxis[v] });
});
Then, if you need to stringify it, you can simply do a JSON.stringify(narray) later on.

You're close:
var seriesValues = [];
for (var abc in objJSON.yAxis) {
seriesValues.push({name: abc, data: objJSON.yAxis[abc]});
}
That will make a javascript array. If you need it as a JSON string then append:
var myString = JSON.stringify(seriesValues);

Simply stringify after the array generated all around.
var result = [];
for(var name in objJSON.yAxis)
{
result.push({name: name, data: objJSON.yAxis[name]});
}
return JSON.stringify(result);

Related

How to create [ 12,24, 13,21] from multi dimensional array

I am really struggling with javascript arrays and objects.
I need to create this structure (array? or ..? unsure of what it is),
data = [ 12, 24, 13, 21]
for a chart.js chart dynamically, from an array.
The array is created as
yAxisArray.push(singularYaxisDataArray);
where
var singularLabelArray = [];
singularLabelArray has values 12, 24, 13, 21 pushed into it.
and 'yAxisArray' could have several singularLabelArray 's in it, which would mean iterating them all
to create several of these structures "data = [ 12, 24, 13, 21]" to put into this
var datasources = [
{
label: "Budgeted",
backgroundColor: 'red',
data: [12, 24, 13, 21]
},
{
label: "Actual",
backgroundColor: "#8e5ea2",
data: [408, 547, 675, 734]
}
];
Iterating the yAxisArray is not the issue , but can't get the structure out of it that I need.
for (idx = 0; idx < yAxisArray.length; idx++)
{
var datasources =
{
label: labelArray[idx],
**data: yAxisArray[idx],**
backgroundColor: colorsList[idx],
}
}
Thank you
declare var outside loop and use push method. Should work.
(If not, Can you add the yAxisArray data and expected)
var datasources = [];
for (idx = 0; idx < yAxisArray.length; idx++) {
datasources.push({
label: labelArray[idx],
data: yAxisArray[idx],
backgroundColor: colorsList[idx],
});
}

How does one process and combine nested array items into a new structure based on requirements?

I'm trying to sum the indices of an array and save them into a new one.
I have included an example array below, as well as my first try to solve this:
var data = [
["29.01.2020", 40, 10],
["30.01.2020", 80, 100],
["31.01.2020", 90, 500],
["01.02.2020", 30, 205],
["02.02.2020", 10, 74],
["03.02.2020", 30, 120]
];
The results I'm trying to create are something like these (either an array or an object):
[['0120', 210, 610], ['0220', 70, 399]]
{
"0120": {
"abc": 210,
"def": 610
},
"0220": {
"abc": 70,
"def": 399
}
}
This is something I found and was playing around with, perhaps something that might work with a little editing:
var res = {};
data.forEach((item)=>{
if(Object.keys(res).includes(item[0])){
res[item[1]] += item[1];
} else {
res[item[0]] = item[1];
}
});
Shortening the first index of my data array should be possible by using substrings I guess? What I'm mainly struggling with is getting it to summarize the index.
Any ideas how I can get there?
Thanks in advance
First, you can get the key from the first element of each subarray using String.split function. Using split function, you can extract the month and year string and combine it to generate the key of each array.
And based on that key, using Array.prototype.reduce, you can generate the content you want.
const data = [
["29.01.2020", 40, 10],
["30.01.2020", 80, 100],
["31.01.2020", 90, 500],
["01.02.2020", 30, 205],
["02.02.2020", 10, 74],
["03.02.2020", 30, 120]
];
const result = data.reduce((acc, cur) => {
const dateArr = cur[0].split('.');
const key = dateArr[1] + dateArr[2].slice(-2);
if (acc[key]) {
acc[key].abc += cur[1];
acc[key].def += cur[2];
} else {
acc[key] = {
abc: cur[1],
def: cur[2]
};
}
return acc;
}, {});
console.log(result);
You can use array reduce method. Split the date string by dot. Then make it a key(according to your requirement two digit from month and last two digit from year) and based on that key just count it. At last using Object.values output the array.
const data = [
['29.01.2020', 40, 10],
['30.01.2020', 80, 100],
['31.01.2020', 90, 500],
['01.02.2020', 30, 205],
['02.02.2020', 10, 74],
['03.02.2020', 30, 120],
];
const ret = data.reduce((prev, c) => {
const p = prev;
const date = c[0].split('.');
const key = `${date[1]}${date[2].slice(-2)}`;
if (!p[key]) p[key] = [key, c[1], c[2]];
else p[key] = [key, p[key][1] + c[1], p[key][2] + c[2]];
return p;
}, {});
console.log(Object.values(ret));

Accessing a JSON integer element

I have an JSON-Object as follows:
Input for the months is
customerSend,customerReceived,totalSendAllCustomers,totalReceivedAllCustomers
var emailObj = {
"kundenNummer":17889,
"jahre":
{
2017:{
"Januar":[15,30,75,125],
"Februar":[17,32,77,127],
"März":[19,34,79,129],
},
2018:{
"Januar":[28,12,66,198],
"Oktober":[40,4,40,5],
}
}
}
How exactly do I access the specific year?
I already tried it like this:
var keysYears = Object.keys(emailObj.jahre);
var currentSelectedYear = keysYears[0];
var keysMonth = Object.keys(emailObj.jahre[currentSelectedYear]);
var currentSelectedMonth = keysMonth[0];
document.write(emailObj.jahre[currentSelectedYear].2017[0]);
I also tried some other ways of doing this but I already deleted those.
Can you tell me how to access the 2017 or 2018 data?
I know that I could convert them into strings but I want to know if I could also do it this way.
You can call the properties of your object emailObj by their names.
Either with a dot notation
emailObj.kundenNummer
Or by brackets notation
emailObj["kundenNummer"]
The dot notation won't work in your case because the name of your property is a number. You should then use
emailObj.jahre["2017"]
var emailObj = {
"kundenNummer": 17889,
"jahre": {
"2017": {
"Januar": [15, 30, 75, 125],
"Februar": [17, 32, 77, 127],
"März": [19, 34, 79, 129],
},
"2018": {
"Januar": [28, 12, 66, 198],
"Oktober": [40, 4, 40, 5],
}
}
};
let year = "2017";
let month = "Januar";
console.log(emailObj.jahre[year][month]);
You should use bracket notation.
document.write(emailObj.jahre[currentSelectedYear][currentSelectedMonth][0]);
var emailObj = {
"kundenNummer":17889,
"jahre":
{
2017:{
"Januar":[15,30,75,125],
"Februar":[17,32,77,127],
"März":[19,34,79,129],
},
2018:{
"Januar":[28,12,66,198],
"Oktober":[40,4,40,5],
}
}
}
var keysYears = Object.keys(emailObj.jahre);
var currentSelectedYear = keysYears[0];
var keysMonth = Object.keys(emailObj.jahre[currentSelectedYear]);
var currentSelectedMonth = keysMonth[0];
document.write(emailObj.jahre[currentSelectedYear][currentSelectedMonth][0]);
In a JavaScript object, the key is always a string, even if you use an integer it will be converted into a string.
obj = {
key1: //contents
key2: //contents
}
To access a specific key:
obj.key1
obj['key1']
For your example:
emailObj.jahre['2017']
emailObj['jahre']['2017']
Use the for in looping construct to loop through the keys of an object:
var emailObj = {
"kundenNummer":17889,
"jahre": {
2017:{
"Januar":[15,30,75,125],
"Februar":[17,32,77,127],
"März":[19,34,79,129],
},
2018:{
"Januar":[28,12,66,198],
"Oktober":[40,4,40,5],
}
}
}
for (key in emailObj.jahre) {
console.log(emailObj.jahre[key]) //Here key will be '2017', '2018' etc
}
You cannot access with dot notation properties which contain as name a number in JavaScript. Instead you should consider using bracket notation.
Example:
emailObj.jahre['2017']
var emailObj = {
"kundenNummer": 17889,
"jahre": {
2017: {
"Januar": [15, 30, 75, 125],
"Februar": [17, 32, 77, 127],
"März": [19, 34, 79, 129],
},
2018: {
"Januar": [28, 12, 66, 198],
"Oktober": [40, 4, 40, 5],
}
}
};
console.log(emailObj['jahre']['2017']);
console.log(emailObj.jahre['2017']);

calculate average result from multi-dimensionally sorted array (JavaScript)

Below is the layout of my JSON File.
{
"questions": ["Question1", "Question2"],
"orgs": ["Org1", "Org2", "Org3"],
"dates": ["Q1", "Q2", "Q3"],
"values": [
[
[5, 88, 18],
[50, 83, 10],
[29, 78, 80]
],
[
[46, 51, 61],
[95, 21, 15],
[49, 86, 43]
]
]
}
I'm trying to retrieve a single array of values by looping through each question, indexed by an "orgs" value and then adding each value retrieved and dividing it by data.dates.length.
Here is my code;
d3.json("data.json", function(error, data) {
var array = new Array()
var orgS = "Org2"
var org = data.orgs.indexOf(orgS);
for (var question = 0; question < data.questions.length; question++) {
array.push(
data.values[question][org]
)
console.log(array)
}
// add array together
array.reduce(function(a, b) {
return a + b;
})
// calculate average
var avg = array / data.dates.length;
})
Here is a plnk;
http://plnkr.co/edit/wMv8GmkD1ynjo9WZVlMb?p=preview
I think the issue here is how I'm retrieving the values in the first place? as at the moment, although I am retrieving the correct values in the console log, I'm getting the array twice, and both times inside nested arrays. I'm not so sure how to remedy the problem?
For reference;
[question1][org1] corresponds to the values [5, 88, 18].
Hope someone can offer some advice here?
Thanks!
Since you clarified your question to indicate you want to calculate separate averages for each question, I've rewritten my answer. You should do all the calculations in the for loop, since the loop is looping through the questions. Then store your averages in an array.
d3.json("data.json", function(error, data) {
var averages = new Array()
var orgS = "Org2"
var org = data.orgs.indexOf(orgS);
var values, sum;
for (var question = 0; question < data.questions.length; question++) {
// get the values for the question/org
values = data.values[question][org];
// calculate the sum
sum = values.reduce(function(a, b) {
return a + b;
});
// calculate the average
averages.push(sum / values.length);
}
console.log(averages);
});
Perform the .reduce() in the for loop and push that result into array. That will give you the an array of the results you expected.
array.push(data.values[question][org].reduce(function(a, b) {
return a + b
}, 0) / data.dates.length)
[
47.666666666666664,
43.666666666666664
]
Currently, you're attempting to perform addition on the arrays themselves in the .reduce() callback instead of reducing the members of each individual array to their sum, and then average.
Demo: (Click the text below to show the whole function)
var data = {
"questions": ["Question1", "Question2"],
"orgs": ["Org1", "Org2", "Org3"],
"dates": ["Q1", "Q2", "Q3"],
"values": [
[
[5, 88, 18],
[50, 83, 10],
[29, 78, 80]
],
[
[46, 51, 61],
[95, 21, 15],
[49, 86, 43]
]
]
}
x(data)
// Your callback function.
function x(data) {
var array = new Array()
var orgS = "Org2"
var org = data.orgs.indexOf(orgS);
for (var question = 0; question < data.questions.length; question++) {
array.push(data.values[question][org].reduce(function(a, b) {
return a + b
}, 0) / data.dates.length)
}
console.log(array)
}
Instead of a for loop, you could also use .map().
var array = data.questions.map(function(_, question) {
return data.values[question][org].reduce(function(a, b) {
return a + b
}, 0) / data.dates.length
})
Demo: (Click the text below to show the whole function)
var data = {
"questions": ["Question1", "Question2"],
"orgs": ["Org1", "Org2", "Org3"],
"dates": ["Q1", "Q2", "Q3"],
"values": [
[
[5, 88, 18],
[50, 83, 10],
[29, 78, 80]
],
[
[46, 51, 61],
[95, 21, 15],
[49, 86, 43]
]
]
}
x(data)
// Your callback function.
function x(data) {
var orgS = "Org2"
var org = data.orgs.indexOf(orgS);
var array = data.questions.map(function(_, question) {
return data.values[question][org].reduce(function(a, b) {
return a + b
}, 0) / data.dates.length
})
console.log(array)
}
You need to store the sum, the result of reduce.
// add array together
// store in sum
var sum = array.reduce(function(a, b) {
return a + b;
}, 0); // use 0 as start value
For the average, you do not need the length of data.dates but from array, because you collecting the values and this length is important.
// calculate average
var avg = sum / array.length;
Together for all values, you might get this
var data = { "questions": ["Question1", "Question2"], "orgs": ["Org1", "Org2", "Org3"], "dates": ["Q1", "Q2", "Q3"], "values": [[[5, 88, 18], [50, 83, 10], [29, 78, 80]], [[46, 51, 61], [95, 21, 15], [49, 86, 43]]] },
sum = [];
data.values.forEach(function (a, i) {
sum[i] = sum[i] || [];
a.forEach(function (b) {
b.forEach(function (c, j) {
sum[i][j] = sum[i][j] || 0;
sum[i][j] += c;
});
});
});
data.avg = sum.map(function (a, i) {
return a.map(function (b) {
return b / data.values[i].length;
});
});
console.log(sum);
console.log(data);

Create an array inside for loop javascript

I am trying to create a dataset pattern like this from the rest service in my angular application.
Example:
$scope.chartSeries = [
{"name": "Google", "data": [100, 200, 400, 700, 300]},
{"name": "Yahoo", "data": [300, 100, null, 500, 200]},
{"name": "Facebook", "data": [500, 200, 200, 300, 500] },
{"name": "Microsoft", "data": [100, 100, 200, 300, 200] }
];
Right now this is my code to build a similar pattern ,
if (datai){
$rootScope.DashboardData =[];
$rootScope.DashboardData = datai;
var _fieldData = [];
widget.chartConfig.series = [];
widget.chartConfig.series =
$rootScope.DashboardData.map(function(elm) {
return {
name: elm[widget.seriesname],
data:_fieldData.push(elm[widget.dataname])
};
});
}
Problem is data field is not creating an array. This is the final output which the above code generates.
[{"name": "Google", "data": 1}];
push() returns the new array's length
$rootScope.DashboardData.map(function(elm)
{
var _fieldData = [];
_fieldData.push(elm[widget.dataname]);
return { name: elm[widget.seriesname], data: _fieldData };
});
or you can use concat()
return { name: elm[widget.seriesname], data: _fieldData.concat(elm[widget.dataname])};
You are assigning _fieldData.push(elm[widget.dataname]) to data and .push() method returns the new array length, so you need to push the element first and then assign the array itself.
_fieldData.push(elm[widget.dataname])
return { name: elm[widget.seriesname], data:_fieldData};
});
try this , You nee a loop for dataname
$rootScope.DashboardData.map(function(elm)
{
var _fieldData = [];
for(var i=0;i<elm[widget.dataname.length;i++)
{
_fieldData.push(elm[widget.dataname][i]);
}
return { name: elm[widget.seriesname], data: _fieldData
});
Array .push() always returns an new length of an array
You should push that variable into _fieldData.push(elm[widget.dataname]); then assign that variable late in data.
$rootScope.DashboardData.map(function(elm)
{
var _fieldData = [].push(elm[widget.dataname]);
return { name: elm[widget.seriesname], data: _fieldData }
});

Categories

Resources